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
e0afb99e
Commit
e0afb99e
authored
Nov 19, 2002
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Plain Diff
Merge kroah.com:/home/linux/linux/BK/bleeding-2.5
into kroah.com:/home/linux/linux/BK/gregkh-2.5
parents
36a04267
827eb892
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
493 additions
and
392 deletions
+493
-392
drivers/usb/media/vicam.c
drivers/usb/media/vicam.c
+117
-117
drivers/usb/net/pegasus.c
drivers/usb/net/pegasus.c
+198
-105
drivers/usb/net/pegasus.h
drivers/usb/net/pegasus.h
+10
-5
drivers/usb/serial/usb-serial.c
drivers/usb/serial/usb-serial.c
+56
-25
drivers/usb/storage/freecom.c
drivers/usb/storage/freecom.c
+21
-35
drivers/usb/storage/isd200.c
drivers/usb/storage/isd200.c
+2
-2
drivers/usb/storage/transport.c
drivers/usb/storage/transport.c
+78
-100
drivers/usb/storage/transport.h
drivers/usb/storage/transport.h
+11
-3
No files found.
drivers/usb/media/vicam.c
View file @
e0afb99e
/*
* USB ViCam WebCam driver
* Copyright (c) 2002 Joe Burks (jburks@wavicle.org)
* Copyright (c) 2002 Joe Burks (jburks@wavicle.org),
* John Tyner (fill in email address)
*
* Supports 3COM HomeConnect PC Digital WebCam
*
...
...
@@ -43,14 +44,6 @@
// #define VICAM_DEBUG
#ifndef MODULE_LICENSE
#define MODULE_LICENSE(a)
#endif
#ifndef bool
#define bool int
#endif
#ifdef VICAM_DEBUG
#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __FUNCTION__, lineno, ##args)
#define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args)
...
...
@@ -403,26 +396,27 @@ static void rvfree(void *mem, unsigned long size)
}
vfree
(
mem
);
}
struct
vicam_camera
{
u16
shutter_speed
;
// capture shutter speed
u16
gain
;
// capture gain
u8
*
raw_image
;
// raw data captured from the camera
u8
*
framebuf
;
// processed data in RGB24 format
u8
*
cntrlbuf
;
// area used to send control msgs
struct
video_device
vdev
;
// v4l video device
struct
usb_device
*
udev
;
// usb device
struct
semaphore
busy_lock
;
// guard against SMP multithreading
bool
is_initialized
;
int
is_initialized
;
u8
open_count
;
u8
bulkEndpoint
;
bool
needsDummyRead
;
int
needsDummyRead
;
#if
def CONFIG_PROC_FS
struct
proc_dir_entry
*
proc_
entry
;
#if
defined(CONFIG_VIDEO_PROC_FS)
struct
proc_dir_entry
*
proc_
dir
;
#endif
};
...
...
@@ -437,22 +431,16 @@ send_control_msg(struct usb_device *udev, u8 request, u16 value, u16 index,
{
int
status
;
// for reasons not yet known to me, you can't send USB control messages
// with data in the module (if you are compiled as a module). Whatever
// the reason, copying it to memory allocated as kernel memory then
// doing the usb control message fixes the problem.
unsigned
char
*
transfer_buffer
=
kmalloc
(
size
,
GFP_KERNEL
);
memcpy
(
transfer_buffer
,
cp
,
size
);
/* cp must be memory that has been allocated by kmalloc */
status
=
usb_control_msg
(
udev
,
usb_sndctrlpipe
(
udev
,
0
),
request
,
USB_DIR_OUT
|
USB_TYPE_VENDOR
|
USB_RECIP_DEVICE
,
value
,
index
,
transfer_buffer
,
size
,
HZ
);
cp
,
size
,
HZ
);
kfree
(
transfer_buffer
);
status
=
min
(
status
,
0
);
if
(
status
<
0
)
{
printk
(
KERN_INFO
"Failed sending control message, error %d.
\n
"
,
...
...
@@ -465,29 +453,30 @@ send_control_msg(struct usb_device *udev, u8 request, u16 value, u16 index,
static
int
initialize_camera
(
struct
vicam_camera
*
cam
)
{
const
struct
{
u8
*
data
;
u32
size
;
}
firmware
[]
=
{
{
.
data
=
setup1
,
.
size
=
sizeof
(
setup1
)
},
{
.
data
=
setup2
,
.
size
=
sizeof
(
setup2
)
},
{
.
data
=
setup3
,
.
size
=
sizeof
(
setup3
)
},
{
.
data
=
setup4
,
.
size
=
sizeof
(
setup4
)
},
{
.
data
=
setup5
,
.
size
=
sizeof
(
setup5
)
},
{
.
data
=
setup3
,
.
size
=
sizeof
(
setup3
)
},
{
.
data
=
NULL
,
.
size
=
0
}
};
struct
usb_device
*
udev
=
cam
->
udev
;
int
status
;
int
err
,
i
;
if
((
status
=
send_control_msg
(
udev
,
0xff
,
0
,
0
,
setup1
,
sizeof
(
setup1
)))
<
0
)
return
status
;
if
((
status
=
send_control_msg
(
udev
,
0xff
,
0
,
0
,
setup2
,
sizeof
(
setup2
)))
<
0
)
return
status
;
if
((
status
=
send_control_msg
(
udev
,
0xff
,
0
,
0
,
setup3
,
sizeof
(
setup3
)))
<
0
)
return
status
;
if
((
status
=
send_control_msg
(
udev
,
0xff
,
0
,
0
,
setup4
,
sizeof
(
setup4
)))
<
0
)
return
status
;
if
((
status
=
send_control_msg
(
udev
,
0xff
,
0
,
0
,
setup5
,
sizeof
(
setup5
)))
<
0
)
return
status
;
if
((
status
=
send_control_msg
(
udev
,
0xff
,
0
,
0
,
setup3
,
sizeof
(
setup3
)))
<
0
)
return
status
;
for
(
i
=
0
,
err
=
0
;
firmware
[
i
].
data
&&
!
err
;
i
++
)
{
memcpy
(
cam
->
cntrlbuf
,
firmware
[
i
].
data
,
firmware
[
i
].
size
);
return
0
;
err
=
send_control_msg
(
udev
,
0xff
,
0
,
0
,
cam
->
cntrlbuf
,
firmware
[
i
].
size
);
}
return
err
;
}
static
int
...
...
@@ -752,7 +741,8 @@ vicam_open(struct inode *inode, struct file *file)
"vicam video_device improperly initialized"
);
}
down_interruptible
(
&
cam
->
busy_lock
);
if
(
down_interruptible
(
&
cam
->
busy_lock
)
)
return
-
EINTR
;
if
(
cam
->
open_count
>
0
)
{
printk
(
KERN_INFO
...
...
@@ -774,6 +764,14 @@ vicam_open(struct inode *inode, struct file *file)
return
-
ENOMEM
;
}
cam
->
cntrlbuf
=
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
if
(
!
cam
->
cntrlbuf
)
{
kfree
(
cam
->
raw_image
);
rvfree
(
cam
->
framebuf
,
VICAM_MAX_FRAME_SIZE
*
VICAM_FRAMES
);
up
(
&
cam
->
busy_lock
);
return
-
ENOMEM
;
}
// First upload firmware, then turn the camera on
if
(
!
cam
->
is_initialized
)
{
...
...
@@ -803,6 +801,7 @@ vicam_close(struct inode *inode, struct file *file)
kfree
(
cam
->
raw_image
);
rvfree
(
cam
->
framebuf
,
VICAM_MAX_FRAME_SIZE
*
VICAM_FRAMES
);
kfree
(
cam
->
cntrlbuf
);
cam
->
open_count
--
;
...
...
@@ -831,7 +830,7 @@ inline void writepixel(char *rgb, int Y, int Cr, int Cb)
// Copyright (C) 2002 Monroe Williams (monroe@pobox.com)
// --------------------------------------------------------------------------------
void
vicam_decode_color
(
char
*
data
,
char
*
rgb
)
static
void
vicam_decode_color
(
char
*
data
,
char
*
rgb
)
{
int
x
,
y
;
int
Cr
,
Cb
;
...
...
@@ -915,7 +914,7 @@ void vicam_decode_color( char *data, char *rgb)
static
void
read_frame
(
struct
vicam_camera
*
cam
,
int
framenum
)
{
unsigned
char
request
[
16
]
;
unsigned
char
*
request
=
cam
->
cntrlbuf
;
int
realShutter
;
int
n
;
int
actual_length
;
...
...
@@ -984,7 +983,8 @@ vicam_read( struct file *file, char *buf, size_t count, loff_t *ppos )
DBG
(
"read %d bytes.
\n
"
,
(
int
)
count
);
down_interruptible
(
&
cam
->
busy_lock
);
if
(
down_interruptible
(
&
cam
->
busy_lock
)
)
return
-
EINTR
;
if
(
*
ppos
>=
VICAM_MAX_FRAME_SIZE
)
{
*
ppos
=
0
;
...
...
@@ -1057,24 +1057,17 @@ vicam_mmap(struct file *file, struct vm_area_struct *vma)
return
0
;
}
#if
def CONFIG_PROC_FS
#if
defined(CONFIG_VIDEO_PROC_FS)
static
struct
proc_dir_entry
*
vicam_proc_root
=
NULL
;
static
int
vicam_read_proc
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
static
int
vicam_read_helper
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
int
value
)
{
char
*
out
=
page
;
int
len
;
struct
vicam_camera
*
cam
=
(
struct
vicam_camera
*
)
data
;
out
+=
sprintf
(
out
,
"Vicam-based WebCam Linux Driver.
\n
"
);
out
+=
sprintf
(
out
,
"(c) 2002 Joe Burks (jburks@wavicle.org)
\n
"
);
out
+=
sprintf
(
out
,
"vicam stats:
\n
"
);
out
+=
sprintf
(
out
,
" Shutter Speed: 1/%d
\n
"
,
cam
->
shutter_speed
);
out
+=
sprintf
(
out
,
" Gain: %d
\n
"
,
cam
->
gain
);
out
+=
sprintf
(
out
,
"%d"
,
value
);
len
=
out
-
page
;
len
-=
off
;
...
...
@@ -1089,38 +1082,43 @@ vicam_read_proc(char *page, char **start, off_t off,
return
len
;
}
static
int
vicam_write_proc
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
static
int
vicam_read_proc_shutter
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
char
*
in
;
char
*
start
;
struct
vicam_camera
*
cam
=
(
struct
vicam_camera
*
)
data
;
in
=
kmalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
!
in
)
return
-
ENOMEM
;
return
vicam_read_helper
(
page
,
start
,
off
,
count
,
eof
,
((
struct
vicam_camera
*
)
data
)
->
shutter_speed
);
}
in
[
count
]
=
0
;
// I'm not sure buffer is gauranteed to be null terminated
// so I do this to make sure I have a null in there.
static
int
vicam_read_proc_gain
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
return
vicam_read_helper
(
page
,
start
,
off
,
count
,
eof
,
((
struct
vicam_camera
*
)
data
)
->
gain
);
}
strncpy
(
in
,
buffer
,
count
);
static
int
vicam_write_proc_shutter
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
struct
vicam_camera
*
cam
=
(
struct
vicam_camera
*
)
data
;
cam
->
shutter_speed
=
simple_strtoul
(
buffer
,
NULL
,
10
);
start
=
strstr
(
in
,
"gain="
);
if
(
start
&&
(
start
==
in
||
*
(
start
-
1
)
==
' '
||
*
(
start
-
1
)
==
','
))
cam
->
gain
=
simple_strtoul
(
start
+
5
,
NULL
,
10
);
return
count
;
}
start
=
strstr
(
in
,
"shutter="
);
if
(
start
&&
(
start
==
in
||
*
(
start
-
1
)
==
' '
||
*
(
start
-
1
)
==
','
))
cam
->
shutter_speed
=
simple_strtoul
(
start
+
8
,
NULL
,
10
);
static
int
vicam_write_proc_gain
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
struct
vicam_camera
*
cam
=
(
struct
vicam_camera
*
)
data
;
cam
->
gain
=
simple_strtoul
(
buffer
,
NULL
,
10
);
kfree
(
in
);
return
count
;
}
void
static
void
vicam_create_proc_root
(
void
)
{
vicam_proc_root
=
create_proc_entry
(
"video/vicam"
,
S_IFDIR
,
0
);
...
...
@@ -1132,19 +1130,17 @@ vicam_create_proc_root(void)
"could not create /proc entry for vicam!"
);
}
void
static
void
vicam_destroy_proc_root
(
void
)
{
if
(
vicam_proc_root
)
remove_proc_entry
(
"video/vicam"
,
0
);
}
void
vicam_create_proc_entry
(
void
*
ptr
)
static
void
vicam_create_proc_entry
(
struct
vicam_camera
*
cam
)
{
struct
vicam_camera
*
cam
=
(
struct
vicam_camera
*
)
ptr
;
char
name
[
7
];
char
name
[
64
];
struct
proc_dir_entry
*
ent
;
DBG
(
KERN_INFO
"vicam: creating proc entry
\n
"
);
...
...
@@ -1158,46 +1154,54 @@ vicam_create_proc_entry(void *ptr)
sprintf
(
name
,
"video%d"
,
cam
->
vdev
.
minor
);
cam
->
proc_dir
=
create_proc_entry
(
name
,
S_IFDIR
,
vicam_proc_root
);
if
(
!
cam
->
proc_dir
)
return
;
// We should probably return an error here
ent
=
create_proc_entry
(
name
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
vicam_proc_root
);
if
(
!
ent
)
return
;
create_proc_entry
(
"shutter"
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
cam
->
proc_dir
);
if
(
ent
)
{
ent
->
data
=
cam
;
ent
->
read_proc
=
vicam_read_proc_shutter
;
ent
->
write_proc
=
vicam_write_proc_shutter
;
ent
->
size
=
64
;
}
ent
->
data
=
cam
;
ent
->
read_proc
=
vicam_read_proc
;
ent
->
write_proc
=
vicam_write_proc
;
ent
->
size
=
512
;
cam
->
proc_entry
=
ent
;
ent
=
create_proc_entry
(
"gain"
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
cam
->
proc_dir
);
if
(
ent
)
{
ent
->
data
=
cam
;
ent
->
read_proc
=
vicam_read_proc_gain
;
ent
->
write_proc
=
vicam_write_proc_gain
;
ent
->
size
=
64
;
}
}
void
static
void
vicam_destroy_proc_entry
(
void
*
ptr
)
{
struct
vicam_camera
*
cam
=
(
struct
vicam_camera
*
)
ptr
;
char
name
[
7
];
char
name
[
16
];
if
(
!
cam
||
!
cam
->
proc_entry
)
if
(
!
cam
->
proc_dir
)
return
;
sprintf
(
name
,
"video%d"
,
cam
->
vdev
.
minor
);
remove_proc_entry
(
name
,
vicam_proc_root
);
cam
->
proc_entry
=
NULL
;
remove_proc_entry
(
"shutter"
,
cam
->
proc_dir
);
remove_proc_entry
(
"gain"
,
cam
->
proc_dir
);
remove_proc_entry
(
name
,
vicam_proc_root
);
cam
->
proc_dir
=
NULL
;
}
#else
static
inline
void
vicam_create_proc_root
(
void
)
{
}
static
inline
void
vicam_destroy_proc_root
(
void
)
{
}
static
inline
void
vicam_create_proc_entry
(
struct
vicam_camera
*
cam
)
{
}
static
inline
void
vicam_destroy_proc_entry
(
void
*
ptr
)
{
}
#endif
int
vicam_video_init
(
struct
video_device
*
vdev
)
{
// This would normally create the proc entry for this camera
#ifdef CONFIG_PROC_FS
vicam_create_proc_entry
(
vdev
->
priv
);
#endif
return
0
;
}
static
struct
file_operations
vicam_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
vicam_open
,
...
...
@@ -1296,6 +1300,8 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id)
return
-
EIO
;
}
vicam_create_proc_entry
(
cam
);
printk
(
KERN_INFO
"ViCam webcam driver now controlling video device %d
\n
"
,
cam
->
vdev
.
minor
);
dev_set_drvdata
(
&
intf
->
dev
,
cam
);
...
...
@@ -1314,9 +1320,7 @@ vicam_disconnect(struct usb_interface *intf)
video_unregister_device
(
&
cam
->
vdev
);
#ifdef CONFIG_PROC_FS
vicam_destroy_proc_entry
(
cam
);
#endif
kfree
(
cam
);
...
...
@@ -1329,9 +1333,7 @@ static int __init
usb_vicam_init
(
void
)
{
DBG
(
KERN_INFO
"ViCam-based WebCam driver startup
\n
"
);
#ifdef CONFIG_PROC_FS
vicam_create_proc_root
();
#endif
if
(
usb_register
(
&
vicam_driver
)
!=
0
)
printk
(
KERN_WARNING
"usb_register failed!
\n
"
);
return
0
;
...
...
@@ -1344,9 +1346,7 @@ usb_vicam_exit(void)
"ViCam-based WebCam driver shutdown
\n
"
);
usb_deregister
(
&
vicam_driver
);
#ifdef CONFIG_PROC_FS
vicam_destroy_proc_root
();
#endif
}
module_init
(
usb_vicam_init
);
...
...
drivers/usb/net/pegasus.c
View file @
e0afb99e
...
...
@@ -28,7 +28,6 @@
* is out of the interrupt routine.
*/
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
...
...
@@ -46,7 +45,7 @@
/*
* Version Information
*/
#define DRIVER_VERSION "v0.5.
6 (2002/06/23
)"
#define DRIVER_VERSION "v0.5.
7 (2002/11/18
)"
#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
#define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
...
...
@@ -119,16 +118,9 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
void
*
data
)
{
int
ret
;
unsigned
char
*
buffer
;
unsigned
char
buffer
[
256
]
;
DECLARE_WAITQUEUE
(
wait
,
current
);
buffer
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
buffer
)
{
err
(
"unable to allocate memory for configuration descriptors"
);
return
0
;
}
memcpy
(
buffer
,
data
,
size
);
add_wait_queue
(
&
pegasus
->
ctrl_wait
,
&
wait
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
while
(
pegasus
->
flags
&
ETH_REGS_CHANGED
)
...
...
@@ -144,9 +136,9 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
pegasus
->
ctrl_urb
->
transfer_buffer_length
=
size
;
usb_fill_control_urb
(
pegasus
->
ctrl_urb
,
pegasus
->
usb
,
usb_rcvctrlpipe
(
pegasus
->
usb
,
0
),
(
char
*
)
&
pegasus
->
dr
,
buffer
,
size
,
ctrl_callback
,
pegasus
);
usb_rcvctrlpipe
(
pegasus
->
usb
,
0
),
(
char
*
)
&
pegasus
->
dr
,
buffer
,
size
,
ctrl_callback
,
pegasus
);
add_wait_queue
(
&
pegasus
->
ctrl_wait
,
&
wait
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
...
...
@@ -161,7 +153,6 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
out:
remove_wait_queue
(
&
pegasus
->
ctrl_wait
,
&
wait
);
memcpy
(
data
,
buffer
,
size
);
kfree
(
buffer
);
return
ret
;
}
...
...
@@ -170,14 +161,9 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
void
*
data
)
{
int
ret
;
unsigned
char
*
buffer
;
unsigned
char
buffer
[
256
]
;
DECLARE_WAITQUEUE
(
wait
,
current
);
buffer
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
buffer
)
{
err
(
"unable to allocate memory for configuration descriptors"
);
return
0
;
}
memcpy
(
buffer
,
data
,
size
);
add_wait_queue
(
&
pegasus
->
ctrl_wait
,
&
wait
);
...
...
@@ -195,9 +181,9 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
pegasus
->
ctrl_urb
->
transfer_buffer_length
=
size
;
usb_fill_control_urb
(
pegasus
->
ctrl_urb
,
pegasus
->
usb
,
usb_sndctrlpipe
(
pegasus
->
usb
,
0
),
(
char
*
)
&
pegasus
->
dr
,
buffer
,
size
,
ctrl_callback
,
pegasus
);
usb_sndctrlpipe
(
pegasus
->
usb
,
0
),
(
char
*
)
&
pegasus
->
dr
,
buffer
,
size
,
ctrl_callback
,
pegasus
);
add_wait_queue
(
&
pegasus
->
ctrl_wait
,
&
wait
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
...
...
@@ -210,7 +196,6 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
schedule
();
out:
remove_wait_queue
(
&
pegasus
->
ctrl_wait
,
&
wait
);
kfree
(
buffer
);
return
ret
;
}
...
...
@@ -218,17 +203,9 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
static
int
set_register
(
pegasus_t
*
pegasus
,
__u16
indx
,
__u8
data
)
{
int
ret
;
unsigned
char
*
buffer
;
__u16
dat
=
data
;
__u16
tmp
=
data
;
DECLARE_WAITQUEUE
(
wait
,
current
);
buffer
=
kmalloc
(
1
,
GFP_KERNEL
);
if
(
!
buffer
)
{
err
(
"unable to allocate memory for configuration descriptors"
);
return
0
;
}
memcpy
(
buffer
,
&
data
,
1
);
add_wait_queue
(
&
pegasus
->
ctrl_wait
,
&
wait
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
while
(
pegasus
->
flags
&
ETH_REGS_CHANGED
)
...
...
@@ -238,15 +215,15 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
pegasus
->
dr
.
bRequestType
=
PEGASUS_REQT_WRITE
;
pegasus
->
dr
.
bRequest
=
PEGASUS_REQ_SET_REG
;
pegasus
->
dr
.
wValue
=
cpu_to_le16p
(
&
dat
);
pegasus
->
dr
.
wValue
=
cpu_to_le16p
(
&
tmp
);
pegasus
->
dr
.
wIndex
=
cpu_to_le16p
(
&
indx
);
pegasus
->
dr
.
wLength
=
cpu_to_le16
(
1
);
pegasus
->
ctrl_urb
->
transfer_buffer_length
=
1
;
usb_fill_control_urb
(
pegasus
->
ctrl_urb
,
pegasus
->
usb
,
usb_sndctrlpipe
(
pegasus
->
usb
,
0
),
(
char
*
)
&
pegasus
->
dr
,
buffer
,
1
,
ctrl_callback
,
pegasus
);
usb_sndctrlpipe
(
pegasus
->
usb
,
0
),
(
char
*
)
&
pegasus
->
dr
,
&
data
,
1
,
ctrl_callback
,
pegasus
);
add_wait_queue
(
&
pegasus
->
ctrl_wait
,
&
wait
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
...
...
@@ -259,7 +236,6 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
schedule
();
out:
remove_wait_queue
(
&
pegasus
->
ctrl_wait
,
&
wait
);
kfree
(
buffer
);
return
ret
;
}
...
...
@@ -276,9 +252,9 @@ static int update_eth_regs_async(pegasus_t * pegasus)
pegasus
->
ctrl_urb
->
transfer_buffer_length
=
3
;
usb_fill_control_urb
(
pegasus
->
ctrl_urb
,
pegasus
->
usb
,
usb_sndctrlpipe
(
pegasus
->
usb
,
0
),
(
char
*
)
&
pegasus
->
dr
,
pegasus
->
eth_regs
,
3
,
ctrl_callback
,
pegasus
);
usb_sndctrlpipe
(
pegasus
->
usb
,
0
),
(
char
*
)
&
pegasus
->
dr
,
pegasus
->
eth_regs
,
3
,
ctrl_callback
,
pegasus
);
if
((
ret
=
usb_submit_urb
(
pegasus
->
ctrl_urb
,
GFP_ATOMIC
)))
err
(
"%s: BAD CTRL %d, flgs %x"
,
__FUNCTION__
,
ret
,
...
...
@@ -294,7 +270,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
__u16
regdi
;
set_register
(
pegasus
,
PhyCtrl
,
0
);
set_registers
(
pegasus
,
PhyAddr
,
sizeof
(
data
),
data
);
set_registers
(
pegasus
,
PhyAddr
,
sizeof
(
data
),
data
);
set_register
(
pegasus
,
PhyCtrl
,
(
indx
|
PHY_READ
));
for
(
i
=
0
;
i
<
REG_TIMEOUT
;
i
++
)
{
get_registers
(
pegasus
,
PhyCtrl
,
1
,
data
);
...
...
@@ -311,6 +287,15 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
return
1
;
}
static
int
mdio_read
(
struct
net_device
*
dev
,
int
phy_id
,
int
loc
)
{
pegasus_t
*
pegasus
=
(
pegasus_t
*
)
dev
->
priv
;
int
res
;
read_mii_word
(
pegasus
,
phy_id
,
loc
,
(
u16
*
)
&
res
);
return
res
&
0xffff
;
}
static
int
write_mii_word
(
pegasus_t
*
pegasus
,
__u8
phy
,
__u8
indx
,
__u16
regd
)
{
int
i
;
...
...
@@ -332,6 +317,13 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd)
return
1
;
}
static
void
mdio_write
(
struct
net_device
*
dev
,
int
phy_id
,
int
loc
,
int
val
)
{
pegasus_t
*
pegasus
=
(
pegasus_t
*
)
dev
->
priv
;
write_mii_word
(
pegasus
,
phy_id
,
loc
,
val
);
}
static
int
read_eprom_word
(
pegasus_t
*
pegasus
,
__u8
index
,
__u16
*
retdata
)
{
int
i
;
...
...
@@ -415,8 +407,8 @@ static void set_ethernet_addr(pegasus_t * pegasus)
__u8
node_id
[
6
];
get_node_id
(
pegasus
,
node_id
);
set_registers
(
pegasus
,
EthID
,
sizeof
(
node_id
),
node_id
);
memcpy
(
pegasus
->
net
->
dev_addr
,
node_id
,
sizeof
(
node_id
));
set_registers
(
pegasus
,
EthID
,
sizeof
(
node_id
),
node_id
);
memcpy
(
pegasus
->
net
->
dev_addr
,
node_id
,
sizeof
(
node_id
));
}
static
inline
int
reset_mac
(
pegasus_t
*
pegasus
)
...
...
@@ -473,7 +465,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
data
[
1
]
=
0
;
data
[
2
]
=
(
loopback
&
1
)
?
0x09
:
0x01
;
memcpy
(
pegasus
->
eth_regs
,
data
,
sizeof
(
data
));
memcpy
(
pegasus
->
eth_regs
,
data
,
sizeof
(
data
));
set_registers
(
pegasus
,
EthCtrl0
,
3
,
data
);
if
(
usb_dev_id
[
pegasus
->
dev_index
].
vendor
==
VENDOR_LINKSYS
||
...
...
@@ -486,18 +478,18 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
return
0
;
}
static
void
fill_skb_pool
(
pegasus_t
*
pegasus
)
static
void
fill_skb_pool
(
pegasus_t
*
pegasus
)
{
int
i
;
for
(
i
=
0
;
i
<
RX_SKBS
;
i
++
)
{
for
(
i
=
0
;
i
<
RX_SKBS
;
i
++
)
{
if
(
pegasus
->
rx_pool
[
i
])
continue
;
pegasus
->
rx_pool
[
i
]
=
dev_alloc_skb
(
PEGASUS_MTU
+
2
);
/*
** we give up if the allocation fail. the tasklet will be
** rescheduled again anyway...
*/
** we give up if the allocation fail. the tasklet will be
** rescheduled again anyway...
*/
if
(
pegasus
->
rx_pool
[
i
]
==
NULL
)
return
;
pegasus
->
rx_pool
[
i
]
->
dev
=
pegasus
->
net
;
...
...
@@ -505,11 +497,11 @@ static void fill_skb_pool(pegasus_t *pegasus)
}
}
static
void
free_skb_pool
(
pegasus_t
*
pegasus
)
static
void
free_skb_pool
(
pegasus_t
*
pegasus
)
{
int
i
;
for
(
i
=
0
;
i
<
RX_SKBS
;
i
++
)
{
for
(
i
=
0
;
i
<
RX_SKBS
;
i
++
)
{
if
(
pegasus
->
rx_pool
[
i
])
{
dev_kfree_skb
(
pegasus
->
rx_pool
[
i
]);
pegasus
->
rx_pool
[
i
]
=
NULL
;
...
...
@@ -517,12 +509,12 @@ static void free_skb_pool(pegasus_t *pegasus)
}
}
static
inline
struct
sk_buff
*
pull_skb
(
pegasus_t
*
pegasus
)
static
inline
struct
sk_buff
*
pull_skb
(
pegasus_t
*
pegasus
)
{
int
i
;
struct
sk_buff
*
skb
;
for
(
i
=
0
;
i
<
RX_SKBS
;
i
++
)
{
for
(
i
=
0
;
i
<
RX_SKBS
;
i
++
)
{
if
(
likely
(
pegasus
->
rx_pool
[
i
]
!=
NULL
))
{
skb
=
pegasus
->
rx_pool
[
i
];
pegasus
->
rx_pool
[
i
]
=
NULL
;
...
...
@@ -563,7 +555,7 @@ static void read_bulk_callback(struct urb *urb)
if
(
!
count
)
goto
goon
;
rx_status
=
le32_to_cpu
(
*
(
int
*
)(
urb
->
transfer_buffer
+
count
-
4
));
rx_status
=
le32_to_cpu
(
*
(
int
*
)
(
urb
->
transfer_buffer
+
count
-
4
));
if
(
rx_status
&
0x000e0000
)
{
dbg
(
"%s: RX packet error %x"
,
net
->
name
,
rx_status
&
0xe0000
);
pegasus
->
stats
.
rx_errors
++
;
...
...
@@ -575,20 +567,24 @@ static void read_bulk_callback(struct urb *urb)
pegasus
->
stats
.
rx_frame_errors
++
;
goto
goon
;
}
pkt_len
=
(
rx_status
&
0xfff
)
-
8
;
if
(
pegasus
->
chip
==
0x8513
)
{
pkt_len
=
le32_to_cpu
(
*
(
int
*
)
urb
->
transfer_buffer
);
pkt_len
&=
0x0fff
;
pegasus
->
rx_skb
->
data
+=
2
;
}
else
{
pkt_len
=
(
rx_status
&
0xfff
)
-
8
;
}
if
(
pegasus
->
rx_skb
==
NULL
)
printk
(
"%s: rx_skb == NULL
\n
"
,
__FUNCTION__
);
/*
** we are sure at this point
pegasus->rx_skb != NULL
*
* so we go ahead and pass up the packet.
*/
* at this point we are sure
pegasus->rx_skb != NULL
* so we go ahead and pass up the packet.
*/
skb_put
(
pegasus
->
rx_skb
,
pkt_len
);
pegasus
->
rx_skb
->
protocol
=
eth_type_trans
(
pegasus
->
rx_skb
,
net
);
netif_rx
(
pegasus
->
rx_skb
);
pegasus
->
stats
.
rx_packets
++
;
pegasus
->
stats
.
rx_bytes
+=
pkt_len
;
spin_lock
(
&
pegasus
->
rx_pool_lock
);
pegasus
->
rx_skb
=
pull_skb
(
pegasus
);
spin_unlock
(
&
pegasus
->
rx_pool_lock
);
...
...
@@ -597,19 +593,19 @@ static void read_bulk_callback(struct urb *urb)
goto
tl_sched
;
goon:
usb_fill_bulk_urb
(
pegasus
->
rx_urb
,
pegasus
->
usb
,
usb_rcvbulkpipe
(
pegasus
->
usb
,
1
),
pegasus
->
rx_skb
->
data
,
PEGASUS_MTU
+
8
,
read_bulk_callback
,
pegasus
);
usb_rcvbulkpipe
(
pegasus
->
usb
,
1
),
pegasus
->
rx_skb
->
data
,
PEGASUS_MTU
+
8
,
read_bulk_callback
,
pegasus
);
if
(
usb_submit_urb
(
pegasus
->
rx_urb
,
GFP_ATOMIC
))
{
pegasus
->
flags
|=
PEGASUS_RX_URB_FAIL
;
goto
tl_sched
;
}
else
{
pegasus
->
flags
&=
~
PEGASUS_RX_URB_FAIL
;
}
return
;
tl_sched:
tl_sched:
tasklet_schedule
(
&
pegasus
->
rx_tl
);
}
...
...
@@ -617,7 +613,7 @@ static void rx_fixup(unsigned long data)
{
pegasus_t
*
pegasus
;
pegasus
=
(
pegasus_t
*
)
data
;
pegasus
=
(
pegasus_t
*
)
data
;
spin_lock_irq
(
&
pegasus
->
rx_pool_lock
);
fill_skb_pool
(
pegasus
);
...
...
@@ -636,9 +632,9 @@ static void rx_fixup(unsigned long data)
return
;
}
usb_fill_bulk_urb
(
pegasus
->
rx_urb
,
pegasus
->
usb
,
usb_rcvbulkpipe
(
pegasus
->
usb
,
1
),
pegasus
->
rx_skb
->
data
,
PEGASUS_MTU
+
8
,
read_bulk_callback
,
pegasus
);
usb_rcvbulkpipe
(
pegasus
->
usb
,
1
),
pegasus
->
rx_skb
->
data
,
PEGASUS_MTU
+
8
,
read_bulk_callback
,
pegasus
);
try_again:
if
(
usb_submit_urb
(
pegasus
->
rx_urb
,
GFP_ATOMIC
))
{
pegasus
->
flags
|=
PEGASUS_RX_URB_FAIL
;
...
...
@@ -704,10 +700,9 @@ static void intr_callback(struct urb *urb)
}
}
status
=
usb_submit_urb
(
urb
,
SLAB_ATOMIC
);
status
=
usb_submit_urb
(
urb
,
SLAB_ATOMIC
);
if
(
status
)
err
(
"%s: can't resubmit interrupt urb, %d"
,
net
->
name
,
status
);
err
(
"%s: can't resubmit interrupt urb, %d"
,
net
->
name
,
status
);
}
static
void
pegasus_tx_timeout
(
struct
net_device
*
net
)
...
...
@@ -735,9 +730,9 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
((
__u16
*
)
pegasus
->
tx_buff
)[
0
]
=
cpu_to_le16
(
l16
);
memcpy
(
pegasus
->
tx_buff
+
2
,
skb
->
data
,
skb
->
len
);
usb_fill_bulk_urb
(
pegasus
->
tx_urb
,
pegasus
->
usb
,
usb_sndbulkpipe
(
pegasus
->
usb
,
2
),
pegasus
->
tx_buff
,
count
,
write_bulk_callback
,
pegasus
);
usb_sndbulkpipe
(
pegasus
->
usb
,
2
),
pegasus
->
tx_buff
,
count
,
write_bulk_callback
,
pegasus
);
if
((
res
=
usb_submit_urb
(
pegasus
->
tx_urb
,
GFP_ATOMIC
)))
{
warn
(
"failed tx_urb %d"
,
res
);
pegasus
->
stats
.
tx_errors
++
;
...
...
@@ -794,7 +789,7 @@ static void set_carrier(struct net_device *net)
}
static
void
free_all_urbs
(
pegasus_t
*
pegasus
)
static
void
free_all_urbs
(
pegasus_t
*
pegasus
)
{
usb_free_urb
(
pegasus
->
intr_urb
);
usb_free_urb
(
pegasus
->
tx_urb
);
...
...
@@ -802,7 +797,7 @@ static void free_all_urbs(pegasus_t *pegasus)
usb_free_urb
(
pegasus
->
ctrl_urb
);
}
static
void
unlink_all_urbs
(
pegasus_t
*
pegasus
)
static
void
unlink_all_urbs
(
pegasus_t
*
pegasus
)
{
usb_unlink_urb
(
pegasus
->
intr_urb
);
usb_unlink_urb
(
pegasus
->
tx_urb
);
...
...
@@ -810,7 +805,7 @@ static void unlink_all_urbs(pegasus_t *pegasus)
usb_unlink_urb
(
pegasus
->
ctrl_urb
);
}
static
int
alloc_urbs
(
pegasus_t
*
pegasus
)
static
int
alloc_urbs
(
pegasus_t
*
pegasus
)
{
pegasus
->
ctrl_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
pegasus
->
ctrl_urb
)
{
...
...
@@ -846,22 +841,22 @@ static int pegasus_open(struct net_device *net)
if
(
pegasus
->
rx_skb
==
NULL
)
pegasus
->
rx_skb
=
pull_skb
(
pegasus
);
/*
** Note: no point to free the pool. it is empty :-)
*/
** Note: no point to free the pool. it is empty :-)
*/
if
(
!
pegasus
->
rx_skb
)
return
-
ENOMEM
;
down
(
&
pegasus
->
sem
);
usb_fill_bulk_urb
(
pegasus
->
rx_urb
,
pegasus
->
usb
,
usb_rcvbulkpipe
(
pegasus
->
usb
,
1
),
pegasus
->
rx_skb
->
data
,
PEGASUS_MTU
+
8
,
read_bulk_callback
,
pegasus
);
usb_rcvbulkpipe
(
pegasus
->
usb
,
1
),
pegasus
->
rx_skb
->
data
,
PEGASUS_MTU
+
8
,
read_bulk_callback
,
pegasus
);
if
((
res
=
usb_submit_urb
(
pegasus
->
rx_urb
,
GFP_KERNEL
)))
warn
(
"%s: failed rx_urb %d"
,
__FUNCTION__
,
res
);
usb_fill_int_urb
(
pegasus
->
intr_urb
,
pegasus
->
usb
,
usb_rcvintpipe
(
pegasus
->
usb
,
3
),
pegasus
->
intr_buff
,
sizeof
(
pegasus
->
intr_buff
),
intr_callback
,
pegasus
,
pegasus
->
intr_interval
);
usb_rcvintpipe
(
pegasus
->
usb
,
3
),
pegasus
->
intr_buff
,
sizeof
(
pegasus
->
intr_buff
),
intr_callback
,
pegasus
,
pegasus
->
intr_interval
);
if
((
res
=
usb_submit_urb
(
pegasus
->
intr_urb
,
GFP_KERNEL
)))
warn
(
"%s: failed intr_urb %d"
,
__FUNCTION__
,
res
);
netif_start_queue
(
net
);
...
...
@@ -896,7 +891,82 @@ static int pegasus_close(struct net_device *net)
return
0
;
}
#ifdef CONFIG_MII
static
int
pegasus_ethtool_ioctl
(
struct
net_device
*
dev
,
void
*
useraddr
)
{
u32
ethcmd
;
pegasus_t
*
pegasus
=
dev
->
priv
;
if
(
copy_from_user
(
&
ethcmd
,
useraddr
,
sizeof
(
ethcmd
)))
return
-
EFAULT
;
switch
(
ethcmd
)
{
/* get driver-specific version/etc. info */
case
ETHTOOL_GDRVINFO
:{
struct
ethtool_drvinfo
info
=
{
ETHTOOL_GDRVINFO
};
strncpy
(
info
.
driver
,
driver_name
,
sizeof
(
info
.
driver
)
-
1
);
strncpy
(
info
.
version
,
DRIVER_VERSION
,
sizeof
(
info
.
version
)
-
1
);
if
(
copy_to_user
(
useraddr
,
&
info
,
sizeof
(
info
)))
return
-
EFAULT
;
return
0
;
}
/* get settings */
case
ETHTOOL_GSET
:{
struct
ethtool_cmd
ecmd
=
{
ETHTOOL_GSET
};
mii_ethtool_gset
(
&
pegasus
->
mii
,
&
ecmd
);
if
(
copy_to_user
(
useraddr
,
&
ecmd
,
sizeof
(
ecmd
)))
return
-
EFAULT
;
return
0
;
}
/* set settings */
case
ETHTOOL_SSET
:{
int
r
;
struct
ethtool_cmd
ecmd
;
if
(
copy_from_user
(
&
ecmd
,
useraddr
,
sizeof
(
ecmd
)))
return
-
EFAULT
;
r
=
mii_ethtool_sset
(
&
pegasus
->
mii
,
&
ecmd
);
return
r
;
}
/* restart autonegotiation */
case
ETHTOOL_NWAY_RST
:{
return
mii_nway_restart
(
&
pegasus
->
mii
);
}
/* get link status */
case
ETHTOOL_GLINK
:{
struct
ethtool_value
edata
=
{
ETHTOOL_GLINK
};
edata
.
data
=
mii_link_ok
(
&
pegasus
->
mii
);
if
(
copy_to_user
(
useraddr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
}
/* get message-level */
case
ETHTOOL_GMSGLVL
:{
struct
ethtool_value
edata
=
{
ETHTOOL_GMSGLVL
};
/* edata.data = pegasus->msg_enable; FIXME */
if
(
copy_to_user
(
useraddr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
}
/* set message-level */
case
ETHTOOL_SMSGLVL
:{
struct
ethtool_value
edata
;
if
(
copy_from_user
(
&
edata
,
useraddr
,
sizeof
(
edata
)))
return
-
EFAULT
;
/* sp->msg_enable = edata.data; FIXME */
return
0
;
}
}
return
-
EOPNOTSUPP
;
}
#else
static
int
pegasus_ethtool_ioctl
(
struct
net_device
*
net
,
void
*
uaddr
)
{
pegasus_t
*
pegasus
;
...
...
@@ -912,8 +982,8 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
strncpy
(
info
.
version
,
DRIVER_VERSION
,
ETHTOOL_BUSINFO_LEN
);
usb_make_path
(
pegasus
->
usb
,
info
.
bus_info
,
sizeof
info
.
bus_info
);
if
(
copy_to_user
(
uaddr
,
&
info
,
sizeof
(
info
)))
sizeof
info
.
bus_info
);
if
(
copy_to_user
(
uaddr
,
&
info
,
sizeof
(
info
)))
return
-
EFAULT
;
return
0
;
}
...
...
@@ -950,7 +1020,7 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
ecmd
.
duplex
=
bmcr
&
BMCR_FULLDPLX
?
DUPLEX_FULL
:
DUPLEX_HALF
;
}
if
(
copy_to_user
(
uaddr
,
&
ecmd
,
sizeof
(
ecmd
)))
if
(
copy_to_user
(
uaddr
,
&
ecmd
,
sizeof
(
ecmd
)))
return
-
EFAULT
;
return
0
;
...
...
@@ -961,7 +1031,7 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
case
ETHTOOL_GLINK
:{
struct
ethtool_value
edata
=
{
ETHTOOL_GLINK
};
edata
.
data
=
netif_carrier_ok
(
net
);
if
(
copy_to_user
(
uaddr
,
&
edata
,
sizeof
(
edata
)))
if
(
copy_to_user
(
uaddr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
}
...
...
@@ -969,7 +1039,7 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
return
-
EOPNOTSUPP
;
}
}
#endif
static
int
pegasus_ioctl
(
struct
net_device
*
net
,
struct
ifreq
*
rq
,
int
cmd
)
{
__u16
*
data
=
(
__u16
*
)
&
rq
->
ifr_data
;
...
...
@@ -1045,8 +1115,26 @@ static __u8 mii_phy_probe(pegasus_t * pegasus)
static
inline
void
setup_pegasus_II
(
pegasus_t
*
pegasus
)
{
u16
data
=
0xa5
;
set_register
(
pegasus
,
Reg1d
,
0
);
set_register
(
pegasus
,
Reg7b
,
1
);
mdelay
(
100
);
set_register
(
pegasus
,
Reg7b
,
2
);
set_register
(
pegasus
,
0x83
,
data
);
get_registers
(
pegasus
,
0x83
,
1
,
&
data
);
if
(
data
==
0xa5
)
{
pegasus
->
chip
=
0x8513
;
}
else
{
pegasus
->
chip
=
0
;
}
set_register
(
pegasus
,
0x80
,
0xc0
);
set_register
(
pegasus
,
0x83
,
0xff
);
set_register
(
pegasus
,
0x84
,
0x01
);
if
(
pegasus
->
features
&
HAS_HOME_PNA
&&
mii_mode
)
set_register
(
pegasus
,
Reg81
,
6
);
else
...
...
@@ -1065,13 +1153,13 @@ static int pegasus_probe(struct usb_interface *intf,
err
(
"usb_set_configuration() failed"
);
return
-
ENODEV
;
}
if
(
!
(
pegasus
=
kmalloc
(
sizeof
(
struct
pegasus
),
GFP_KERNEL
)))
{
if
(
!
(
pegasus
=
kmalloc
(
sizeof
(
struct
pegasus
),
GFP_KERNEL
)))
{
err
(
"out of memory allocating device structure"
);
return
-
ENOMEM
;
}
usb_get_dev
(
dev
);
memset
(
pegasus
,
0
,
sizeof
(
struct
pegasus
));
memset
(
pegasus
,
0
,
sizeof
(
struct
pegasus
));
pegasus
->
dev_index
=
dev_index
;
init_waitqueue_head
(
&
pegasus
->
ctrl_wait
);
...
...
@@ -1088,8 +1176,8 @@ static int pegasus_probe(struct usb_interface *intf,
}
init_MUTEX
(
&
pegasus
->
sem
);
tasklet_init
(
&
pegasus
->
rx_tl
,
rx_fixup
,
(
unsigned
long
)
pegasus
);
tasklet_init
(
&
pegasus
->
rx_tl
,
rx_fixup
,
(
unsigned
long
)
pegasus
);
down
(
&
pegasus
->
sem
);
pegasus
->
usb
=
dev
;
pegasus
->
net
=
net
;
...
...
@@ -1104,6 +1192,11 @@ static int pegasus_probe(struct usb_interface *intf,
net
->
set_multicast_list
=
pegasus_set_multicast
;
net
->
get_stats
=
pegasus_netdev_stats
;
net
->
mtu
=
PEGASUS_MTU
;
pegasus
->
mii
.
dev
=
net
;
pegasus
->
mii
.
mdio_read
=
mdio_read
;
pegasus
->
mii
.
mdio_write
=
mdio_write
;
pegasus
->
mii
.
phy_id_mask
=
0x1f
;
pegasus
->
mii
.
reg_num_mask
=
0x1f
;
spin_lock_init
(
&
pegasus
->
rx_pool_lock
);
pegasus
->
features
=
usb_dev_id
[
dev_index
].
private
;
...
...
@@ -1132,7 +1225,7 @@ static int pegasus_probe(struct usb_interface *intf,
exit:
up
(
&
pegasus
->
sem
);
if
(
pegasus
)
{
dev_set_drvdata
(
&
intf
->
dev
,
pegasus
);
dev_set_drvdata
(
&
intf
->
dev
,
pegasus
);
return
0
;
}
return
-
EIO
;
...
...
@@ -1140,9 +1233,9 @@ static int pegasus_probe(struct usb_interface *intf,
static
void
pegasus_disconnect
(
struct
usb_interface
*
intf
)
{
struct
pegasus
*
pegasus
=
dev_get_drvdata
(
&
intf
->
dev
);
struct
pegasus
*
pegasus
=
dev_get_drvdata
(
&
intf
->
dev
);
dev_set_drvdata
(
&
intf
->
dev
,
NULL
);
dev_set_drvdata
(
&
intf
->
dev
,
NULL
);
if
(
!
pegasus
)
{
warn
(
"unregistering non-existant device"
);
return
;
...
...
@@ -1162,10 +1255,10 @@ static void pegasus_disconnect(struct usb_interface *intf)
}
static
struct
usb_driver
pegasus_driver
=
{
.
name
=
driver_name
,
.
probe
=
pegasus_probe
,
.
disconnect
=
pegasus_disconnect
,
.
id_table
=
pegasus_ids
,
.
name
=
driver_name
,
.
probe
=
pegasus_probe
,
.
disconnect
=
pegasus_disconnect
,
.
id_table
=
pegasus_ids
,
};
int
__init
pegasus_init
(
void
)
...
...
drivers/usb/net/pegasus.h
View file @
e0afb99e
...
...
@@ -85,6 +85,7 @@ typedef struct pegasus {
struct
usb_device
*
usb
;
struct
net_device
*
net
;
struct
net_device_stats
stats
;
struct
mii_if_info
mii
;
unsigned
flags
;
unsigned
features
;
int
dev_index
;
...
...
@@ -97,6 +98,7 @@ typedef struct pegasus {
wait_queue_head_t
ctrl_wait
;
struct
semaphore
sem
;
spinlock_t
rx_pool_lock
;
int
chip
;
unsigned
char
intr_buff
[
8
];
__u8
tx_buff
[
PEGASUS_MTU
];
__u8
eth_regs
[
4
];
...
...
@@ -131,11 +133,11 @@ struct usb_eth_dev {
#define VENDOR_LANEED 0x056e
#define VENDOR_LINKSYS 0x066b
#define VENDOR_MELCO 0x0411
#define VENDOR_NETGEAR 0x0846
#define VENDOR_SMARTBRIDGES 0x08d1
#define VENDOR_SMC 0x0707
#define VENDOR_SOHOWARE 0x15e8
#define VENDOR_SIEMENS 0x067c
#define VENDOR_JTEC 0x11ad
#else
/* PEGASUS_DEV */
...
...
@@ -169,7 +171,10 @@ PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
PEGASUS_DEV
(
"ADMtek ADM8511
\"
Pegasus II
\"
USB Ethernet"
,
VENDOR_ADMTEK
,
0x8511
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"ADMtek AN986
\"
Pegasus
\"
USB Ethernet (eval. board)"
,
PEGASUS_DEV
(
"ADMtek ADM8513
\"
Pegasus II
\"
USB Ethernet"
,
VENDOR_ADMTEK
,
0x8513
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"ADMtek AN986
\"
Pegasus
\"
USB Ethernet (evaluation board)"
,
VENDOR_ADMTEK
,
0x0986
,
DEFAULT_GPIO_RESET
|
HAS_HOME_PNA
)
PEGASUS_DEV
(
"AN986A USB MAC"
,
VENDOR_ADMTEK
,
1986
,
...
...
@@ -192,7 +197,7 @@ PEGASUS_DEV( "Billionton USBE-100", VENDOR_BILLIONTON, 0x8511,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"Corega FEter USB-TX"
,
VENDOR_COREGA
,
0x0004
,
DEFAULT_GPIO_RESET
)
PEGASUS_DEV
(
"Corega FEter"
,
VENDOR_COREGA
,
0x000d
,
PEGASUS_DEV
(
"Corega FEter
USB-TXS
"
,
VENDOR_COREGA
,
0x000d
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"D-Link DSB-650TX"
,
VENDOR_DLINK
,
0x4001
,
LINKSYS_GPIO_RESET
)
...
...
@@ -246,6 +251,8 @@ PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005,
DEFAULT_GPIO_RESET
)
PEGASUS_DEV
(
"MELCO/BUFFALO LUA2-TX"
,
VENDOR_MELCO
,
0x0009
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"NETGEAR FA101"
,
VENDOR_NETGEAR
,
0x1020
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"smartNIC 2 PnP Adapter"
,
VENDOR_SMARTBRIDGES
,
0x0003
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"SMC 202 USB Ethernet"
,
VENDOR_SMC
,
0x0200
,
...
...
@@ -258,8 +265,6 @@ PEGASUS_DEV( "SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"SpeedStream USB 10/100 Ethernet"
,
VENDOR_SIEMENS
,
0x1001
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"FA8101 USB To ETHERNET"
,
VENDOR_JTEC
,
0x8101
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
#endif
/* PEGASUS_DEV */
drivers/usb/serial/usb-serial.c
View file @
e0afb99e
...
...
@@ -14,6 +14,10 @@
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
* (11/19/2002) gkh
* removed a few #ifdefs for the generic code and cleaned up the failure
* logic in initialization.
*
* (10/02/2002) gkh
* moved the console code to console.c and out of this file.
*
...
...
@@ -341,7 +345,7 @@
/*
* Version Information
*/
#define DRIVER_VERSION "v1.
6
"
#define DRIVER_VERSION "v1.
7
"
#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
#define DRIVER_DESC "USB Serial Driver core"
...
...
@@ -382,7 +386,29 @@ static struct usb_device_id generic_serial_ids[] = {
{.
driver_info
=
42
},
{}
};
#endif
static
int
generic_register
(
void
)
{
generic_device_ids
[
0
].
idVendor
=
vendor
;
generic_device_ids
[
0
].
idProduct
=
product
;
generic_device_ids
[
0
].
match_flags
=
USB_DEVICE_ID_MATCH_VENDOR
|
USB_DEVICE_ID_MATCH_PRODUCT
;
/* register our generic driver with ourselves */
return
usb_serial_register
(
&
generic_device
);
}
static
void
generic_deregister
(
void
)
{
/* remove our generic driver */
usb_serial_deregister
(
&
generic_device
);
}
#else
static
inline
int
generic_register
(
void
)
{
return
0
;
}
static
inline
void
generic_deregister
(
void
)
{
}
#endif
/* CONFIG_USB_SERIAL_GENERIC */
/* Driver structure we register with the USB core */
static
struct
usb_driver
usb_serial_driver
=
{
...
...
@@ -409,7 +435,6 @@ static struct termios * serial_termios_locked[SERIAL_TTY_MINORS];
static
struct
usb_serial
*
serial_table
[
SERIAL_TTY_MINORS
];
/* initially all NULL */
static
LIST_HEAD
(
usb_serial_driver_list
);
struct
usb_serial
*
usb_serial_get_by_minor
(
unsigned
int
minor
)
{
return
serial_table
[
minor
];
...
...
@@ -839,7 +864,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
length
+=
sprintf
(
page
+
length
,
"%d:"
,
i
);
if
(
serial
->
type
->
owner
)
length
+=
sprintf
(
page
+
length
,
" module:%s"
,
serial
->
type
->
owner
->
name
);
length
+=
sprintf
(
page
+
length
,
" module:%s"
,
module_name
(
serial
->
type
->
owner
)
);
length
+=
sprintf
(
page
+
length
,
" name:
\"
%s
\"
"
,
serial
->
type
->
name
);
length
+=
sprintf
(
page
+
length
,
" vendor:%04x product:%04x"
,
serial
->
vendor
,
serial
->
product
);
length
+=
sprintf
(
page
+
length
,
" num_ports:%d"
,
serial
->
num_ports
);
...
...
@@ -1574,40 +1599,49 @@ static struct tty_driver serial_tty_driver = {
static
int
__init
usb_serial_init
(
void
)
{
int
i
;
int
result
;
int
result
=
0
;
/* Initalize our global data */
for
(
i
=
0
;
i
<
SERIAL_TTY_MINORS
;
++
i
)
{
serial_table
[
i
]
=
NULL
;
}
/* register the generic driver, if we should */
result
=
generic_register
();
if
(
result
<
0
)
{
err
(
"%s - registering generic driver failed"
,
__FUNCTION__
);
goto
exit
;
}
/* register the tty driver */
serial_tty_driver
.
init_termios
=
tty_std_termios
;
serial_tty_driver
.
init_termios
.
c_cflag
=
B9600
|
CS8
|
CREAD
|
HUPCL
|
CLOCAL
;
if
(
tty_register_driver
(
&
serial_tty_driver
))
{
err
(
"%s - failed to register tty driver"
,
__FUNCTION__
);
return
-
1
;
result
=
tty_register_driver
(
&
serial_tty_driver
);
if
(
result
)
{
err
(
"%s - tty_register_driver failed"
,
__FUNCTION__
);
goto
exit_generic
;
}
/* register the USB driver */
result
=
usb_register
(
&
usb_serial_driver
);
if
(
result
<
0
)
{
tty_unregister_driver
(
&
serial_tty_driver
);
err
(
"usb_register failed for the usb-serial driver. Error number %d"
,
result
);
return
-
1
;
err
(
"%s - usb_register failed"
,
__FUNCTION__
);
goto
exit_tty
;
}
#ifdef CONFIG_USB_SERIAL_GENERIC
generic_device_ids
[
0
].
idVendor
=
vendor
;
generic_device_ids
[
0
].
idProduct
=
product
;
generic_device_ids
[
0
].
match_flags
=
USB_DEVICE_ID_MATCH_VENDOR
|
USB_DEVICE_ID_MATCH_PRODUCT
;
/* register our generic driver with ourselves */
usb_serial_register
(
&
generic_device
);
#endif
info
(
DRIVER_DESC
" "
DRIVER_VERSION
);
return
0
;
return
result
;
exit_tty:
tty_unregister_driver
(
&
serial_tty_driver
);
exit_generic:
generic_deregister
();
exit:
err
(
"%s - returning with error %d"
,
__FUNCTION__
,
result
);
return
result
;
}
...
...
@@ -1615,11 +1649,8 @@ static void __exit usb_serial_exit(void)
{
usb_serial_console_exit
();
#ifdef CONFIG_USB_SERIAL_GENERIC
/* remove our generic driver */
usb_serial_deregister
(
&
generic_device
);
#endif
generic_deregister
();
usb_deregister
(
&
usb_serial_driver
);
tty_unregister_driver
(
&
serial_tty_driver
);
}
...
...
drivers/usb/storage/freecom.c
View file @
e0afb99e
...
...
@@ -115,7 +115,7 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
freecom_udata_t
extra
=
(
freecom_udata_t
)
us
->
extra
;
struct
freecom_xfer_wrap
*
fxfr
=
(
struct
freecom_xfer_wrap
*
)
extra
->
buffer
;
int
result
,
partial
;
int
result
;
fxfr
->
Type
=
FCM_PACKET_INPUT
|
0x00
;
fxfr
->
Timeout
=
0
;
/* Short timeout for debugging. */
...
...
@@ -125,14 +125,12 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
US_DEBUGP
(
"Read data Freecom! (c=%d)
\n
"
,
count
);
/* Issue the transfer command. */
result
=
usb_stor_bulk_
msg
(
us
,
fxfr
,
opipe
,
FCM_PACKET_LENGTH
,
&
partial
);
result
=
usb_stor_bulk_
transfer_buf
(
us
,
opipe
,
fxfr
,
FCM_PACKET_LENGTH
,
NULL
);
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
US_DEBUGP
(
"Freecom readdata xport failure: r=%d, p=%d
\n
"
,
result
,
partial
);
US_DEBUGP
(
"Freecom readdata transport error
\n
"
);
return
USB_STOR_TRANSPORT_ERROR
;
}
US_DEBUGP
(
"Done issuing read request: %d %d
\n
"
,
result
,
partial
);
/* Now transfer all of our blocks. */
US_DEBUGP
(
"Start of read
\n
"
);
...
...
@@ -151,7 +149,7 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
freecom_udata_t
extra
=
(
freecom_udata_t
)
us
->
extra
;
struct
freecom_xfer_wrap
*
fxfr
=
(
struct
freecom_xfer_wrap
*
)
extra
->
buffer
;
int
result
,
partial
;
int
result
;
fxfr
->
Type
=
FCM_PACKET_OUTPUT
|
0x00
;
fxfr
->
Timeout
=
0
;
/* Short timeout for debugging. */
...
...
@@ -161,15 +159,12 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
US_DEBUGP
(
"Write data Freecom! (c=%d)
\n
"
,
count
);
/* Issue the transfer command. */
result
=
usb_stor_bulk_
msg
(
us
,
fxfr
,
opipe
,
FCM_PACKET_LENGTH
,
&
partial
);
result
=
usb_stor_bulk_
transfer_buf
(
us
,
opipe
,
fxfr
,
FCM_PACKET_LENGTH
,
NULL
);
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
US_DEBUGP
(
"Freecom writedata xport failure: r=%d, p=%d
\n
"
,
result
,
partial
);
US_DEBUGP
(
"Freecom writedata transport error
\n
"
);
return
USB_STOR_TRANSPORT_ERROR
;
}
US_DEBUGP
(
"Done issuing write request: %d %d
\n
"
,
result
,
partial
);
/* Now transfer all of our blocks. */
US_DEBUGP
(
"Start of write
\n
"
);
...
...
@@ -191,7 +186,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
struct
freecom_status
*
fst
;
unsigned
int
ipipe
,
opipe
;
/* We need both pipes. */
int
result
;
int
partial
;
unsigned
int
partial
;
int
length
;
freecom_udata_t
extra
;
...
...
@@ -215,23 +210,22 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUG
(
pdump
(
srb
->
cmnd
,
12
));
/* Send it out. */
result
=
usb_stor_bulk_
msg
(
us
,
fcb
,
opipe
,
FCM_PACKET_LENGTH
,
&
partial
);
result
=
usb_stor_bulk_
transfer_buf
(
us
,
opipe
,
fcb
,
FCM_PACKET_LENGTH
,
NULL
);
/* The Freecom device will only fail if there is something wrong in
* USB land. It returns the status in its own registers, which
* come back in the bulk pipe. */
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
US_DEBUGP
(
"freecom xport failure: r=%d, p=%d
\n
"
,
result
,
partial
);
US_DEBUGP
(
"freecom transport error
\n
"
);
return
USB_STOR_TRANSPORT_ERROR
;
}
/* There are times we can optimize out this status read, but it
* doesn't hurt us to always do it now. */
result
=
usb_stor_bulk_
msg
(
us
,
fst
,
ipipe
,
result
=
usb_stor_bulk_
transfer_buf
(
us
,
ipipe
,
fst
,
FCM_PACKET_LENGTH
,
&
partial
);
US_DEBUGP
(
"foo Status result %d %
d
\n
"
,
result
,
partial
);
US_DEBUGP
(
"foo Status result %d %
u
\n
"
,
result
,
partial
);
if
(
result
!=
USB_STOR_XFER_GOOD
)
return
USB_STOR_TRANSPORT_ERROR
;
...
...
@@ -256,24 +250,23 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
memset
(
fcb
->
Filler
,
0
,
sizeof
(
fcb
->
Filler
));
/* Send it out. */
result
=
usb_stor_bulk_
msg
(
us
,
fcb
,
opipe
,
FCM_PACKET_LENGTH
,
&
partial
);
result
=
usb_stor_bulk_
transfer_buf
(
us
,
opipe
,
fcb
,
FCM_PACKET_LENGTH
,
NULL
);
/* The Freecom device will only fail if there is something
* wrong in USB land. It returns the status in its own
* registers, which come back in the bulk pipe.
*/
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
US_DEBUGP
(
"freecom xport failure: r=%d, p=%d
\n
"
,
result
,
partial
);
US_DEBUGP
(
"freecom transport error
\n
"
);
return
USB_STOR_TRANSPORT_ERROR
;
}
/* get the data */
result
=
usb_stor_bulk_
msg
(
us
,
fst
,
ipipe
,
result
=
usb_stor_bulk_
transfer_buf
(
us
,
ipipe
,
fst
,
FCM_PACKET_LENGTH
,
&
partial
);
US_DEBUGP
(
"bar Status result %d %
d
\n
"
,
result
,
partial
);
US_DEBUGP
(
"bar Status result %d %
u
\n
"
,
result
,
partial
);
if
(
result
>
USB_STOR_XFER_SHORT
)
return
USB_STOR_TRANSPORT_ERROR
;
...
...
@@ -328,7 +321,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
return
result
;
US_DEBUGP
(
"FCM: Waiting for status
\n
"
);
result
=
usb_stor_bulk_
msg
(
us
,
fst
,
ipipe
,
result
=
usb_stor_bulk_
transfer_buf
(
us
,
ipipe
,
fst
,
FCM_PACKET_LENGTH
,
&
partial
);
US_DEBUG
(
pdump
((
void
*
)
fst
,
partial
));
...
...
@@ -354,7 +347,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
return
result
;
US_DEBUGP
(
"FCM: Waiting for status
\n
"
);
result
=
usb_stor_bulk_
msg
(
us
,
fst
,
ipipe
,
result
=
usb_stor_bulk_
transfer_buf
(
us
,
ipipe
,
fst
,
FCM_PACKET_LENGTH
,
&
partial
);
if
(
partial
!=
4
||
result
>
USB_STOR_XFER_SHORT
)
...
...
@@ -385,13 +378,6 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
}
return
USB_STOR_TRANSPORT_GOOD
;
US_DEBUGP
(
"Freecom: transfer_length = %d
\n
"
,
usb_stor_transfer_length
(
srb
));
US_DEBUGP
(
"Freecom: direction = %d
\n
"
,
srb
->
sc_data_direction
);
return
USB_STOR_TRANSPORT_ERROR
;
}
int
...
...
drivers/usb/storage/isd200.c
View file @
e0afb99e
...
...
@@ -668,7 +668,7 @@ int isd200_write_config( struct us_data *us )
#endif
/* let's send the command via the control pipe */
result
=
usb_stor_c
ontrol_msg
(
result
=
usb_stor_c
trl_transfer
(
us
,
us
->
send_ctrl_pipe
,
0x01
,
...
...
@@ -709,7 +709,7 @@ int isd200_read_config( struct us_data *us )
/* read the configuration information from ISD200. Use this to */
/* determine what the special ATA CDB bytes are. */
result
=
usb_stor_c
ontrol_msg
(
result
=
usb_stor_c
trl_transfer
(
us
,
us
->
recv_ctrl_pipe
,
0x02
,
...
...
drivers/usb/storage/transport.c
View file @
e0afb99e
...
...
@@ -479,7 +479,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
usb_stor_blocking_completion
,
NULL
);
status
=
usb_stor_msg_common
(
us
);
/* return the actual length of the data transferred if no error*/
/* return the actual length of the data transferred if no error
*/
if
(
status
>=
0
)
status
=
us
->
current_urb
->
actual_length
;
return
status
;
...
...
@@ -543,47 +543,91 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
return
0
;
}
/*
*
Transfer one control message
*
Interpret the results of a URB transfer
*
* This function
does basically the same thing as usb_stor_control_msg()
*
above, except that return codes are USB_STOR_XFER_xxx rather than the
*
urb status or transfer length
.
* This function
prints appropriate debugging messages, clears halts on
*
bulk endpoints, and translates the status to the corresponding
*
USB_STOR_XFER_xxx return code
.
*/
int
usb_stor_ctrl_transfer
(
struct
us_data
*
us
,
unsigned
int
pipe
,
u8
request
,
u8
requesttype
,
u16
value
,
u16
index
,
void
*
data
,
u16
size
)
{
int
result
;
static
int
interpret_urb_result
(
struct
us_data
*
us
,
unsigned
int
pipe
,
unsigned
int
length
,
int
result
,
unsigned
int
partial
)
{
US_DEBUGP
(
"usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x "
"value=%04x index=%02x len=%d
\n
"
,
request
,
requesttype
,
value
,
index
,
size
);
result
=
usb_stor_control_msg
(
us
,
pipe
,
request
,
requesttype
,
value
,
index
,
data
,
size
);
US_DEBUGP
(
"usb_stor_control_msg returned %d
\n
"
,
result
);
US_DEBUGP
(
"Status code %d; transferred %u/%u
\n
"
,
result
,
partial
,
length
);
/*
a stall indicates a protocol error
*/
/*
stalled
*/
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"-- stall on control pipe
\n
"
);
/* for non-bulk (i.e., control) endpoints, a stall indicates
* a protocol error */
if
(
!
usb_pipebulk
(
pipe
))
{
US_DEBUGP
(
"-- stall on control pipe
\n
"
);
return
USB_STOR_XFER_ERROR
;
}
/* for a bulk endpoint, clear the stall */
US_DEBUGP
(
"clearing endpoint halt for pipe 0x%x
\n
"
,
pipe
);
if
(
usb_stor_clear_halt
(
us
,
pipe
)
<
0
)
return
USB_STOR_XFER_ERROR
;
return
USB_STOR_XFER_STALLED
;
}
/* NAK - that means we've retried this a few times already */
if
(
result
==
-
ETIMEDOUT
)
{
US_DEBUGP
(
"-- device NAKed
\n
"
);
return
USB_STOR_XFER_ERROR
;
}
/* the transfer was cancelled, presumably by an abort */
if
(
result
==
-
ENODEV
)
{
US_DEBUGP
(
"-- transfer cancelled
\n
"
);
return
USB_STOR_XFER_ERROR
;
}
/*
some other serious problem her
e */
/*
the catch-all error cas
e */
if
(
result
<
0
)
{
US_DEBUGP
(
"-- unknown error
\n
"
);
return
USB_STOR_XFER_ERROR
;
}
/*
was the entire command transferred
? */
if
(
result
<
size
)
{
US_DEBUGP
(
"-- transferred only %
d bytes
\n
"
,
result
);
/*
no error code; did we send all the data
? */
if
(
partial
!=
length
)
{
US_DEBUGP
(
"-- transferred only %
u bytes
\n
"
,
partial
);
return
USB_STOR_XFER_SHORT
;
}
US_DEBUGP
(
"-- transfer complete
d successfully
\n
"
);
US_DEBUGP
(
"-- transfer complete
\n
"
);
return
USB_STOR_XFER_GOOD
;
}
/*
* Transfer one control message
*
* This function does basically the same thing as usb_stor_control_msg()
* above, except that return codes are USB_STOR_XFER_xxx rather than the
* urb status or transfer length.
*/
int
usb_stor_ctrl_transfer
(
struct
us_data
*
us
,
unsigned
int
pipe
,
u8
request
,
u8
requesttype
,
u16
value
,
u16
index
,
void
*
data
,
u16
size
)
{
int
result
;
unsigned
int
partial
=
0
;
US_DEBUGP
(
"usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x "
"value=%04x index=%02x len=%u
\n
"
,
request
,
requesttype
,
value
,
index
,
size
);
result
=
usb_stor_control_msg
(
us
,
pipe
,
request
,
requesttype
,
value
,
index
,
data
,
size
);
if
(
result
>
0
)
{
/* Separate out the amount transferred */
partial
=
result
;
result
=
0
;
}
return
interpret_urb_result
(
us
,
pipe
,
size
,
result
,
partial
);
}
/*
* Transfer one buffer via bulk transfer
*
...
...
@@ -596,50 +640,17 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
* urb status or transfer length.
*/
int
usb_stor_bulk_transfer_buf
(
struct
us_data
*
us
,
unsigned
int
pipe
,
char
*
buf
,
unsigned
int
length
,
unsigned
int
*
act_len
)
void
*
buf
,
unsigned
int
length
,
unsigned
int
*
act_len
)
{
int
result
;
int
partial
;
unsigned
int
partial
;
/* transfer the data */
US_DEBUGP
(
"usb_stor_bulk_transfer_buf(): xfer %
d
bytes
\n
"
,
length
);
US_DEBUGP
(
"usb_stor_bulk_transfer_buf(): xfer %
u
bytes
\n
"
,
length
);
result
=
usb_stor_bulk_msg
(
us
,
buf
,
pipe
,
length
,
&
partial
);
US_DEBUGP
(
"usb_stor_bulk_msg() returned %d xferred %d/%d
\n
"
,
result
,
partial
,
length
);
if
(
act_len
)
*
act_len
=
partial
;
/* if we stall, we need to clear it before we go on */
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"clearing endpoint halt for pipe 0x%x,"
" stalled at %d bytes
\n
"
,
pipe
,
partial
);
if
(
usb_stor_clear_halt
(
us
,
pipe
)
<
0
)
return
USB_STOR_XFER_ERROR
;
return
USB_STOR_XFER_STALLED
;
}
/* NAK - that means we've retried a few times already */
if
(
result
==
-
ETIMEDOUT
)
{
US_DEBUGP
(
"-- device NAKed
\n
"
);
return
USB_STOR_XFER_ERROR
;
}
/* the catch-all error case */
if
(
result
)
{
US_DEBUGP
(
"-- unknown error
\n
"
);
return
USB_STOR_XFER_ERROR
;
}
/* did we send all the data? */
if
(
partial
==
length
)
{
US_DEBUGP
(
"-- transfer complete
\n
"
);
return
USB_STOR_XFER_GOOD
;
}
/* no error code, so we must have transferred some data,
* just not all of it */
US_DEBUGP
(
"-- transferred only %d bytes
\n
"
,
partial
);
return
USB_STOR_XFER_SHORT
;
return
interpret_urb_result
(
us
,
pipe
,
length
,
result
,
partial
);
}
/*
...
...
@@ -653,10 +664,10 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
unsigned
int
*
act_len
)
{
int
result
;
int
partial
;
unsigned
int
partial
;
/* initialize the scatter-gather request block */
US_DEBUGP
(
"usb_stor_bulk_transfer_sglist(): xfer %
d
bytes, "
US_DEBUGP
(
"usb_stor_bulk_transfer_sglist(): xfer %
u
bytes, "
"%d entries
\n
"
,
length
,
num_sg
);
result
=
usb_sg_init
(
us
->
current_sg
,
us
->
pusb_dev
,
pipe
,
0
,
sg
,
num_sg
,
length
,
SLAB_NOIO
);
...
...
@@ -685,55 +696,22 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
result
=
us
->
current_sg
->
status
;
partial
=
us
->
current_sg
->
bytes
;
US_DEBUGP
(
"usb_sg_wait() returned %d xferred %d/%d
\n
"
,
result
,
partial
,
length
);
if
(
act_len
)
*
act_len
=
partial
;
/* if we stall, we need to clear it before we go on */
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"clearing endpoint halt for pipe 0x%x, "
"stalled at %d bytes
\n
"
,
pipe
,
partial
);
if
(
usb_stor_clear_halt
(
us
,
pipe
)
<
0
)
return
USB_STOR_XFER_ERROR
;
return
USB_STOR_XFER_STALLED
;
}
/* NAK - that means we've retried this a few times already */
if
(
result
==
-
ETIMEDOUT
)
{
US_DEBUGP
(
"-- device NAKed
\n
"
);
return
USB_STOR_XFER_ERROR
;
}
/* the catch-all error case */
if
(
result
)
{
US_DEBUGP
(
"-- unknown error
\n
"
);
return
USB_STOR_XFER_ERROR
;
}
/* did we send all the data? */
if
(
partial
==
length
)
{
US_DEBUGP
(
"-- transfer complete
\n
"
);
return
USB_STOR_XFER_GOOD
;
}
/* no error code, so we must have transferred some data,
* just not all of it */
US_DEBUGP
(
"-- transferred only %d bytes
\n
"
,
partial
);
return
USB_STOR_XFER_SHORT
;
return
interpret_urb_result
(
us
,
pipe
,
length
,
result
,
partial
);
}
/*
* Transfer an entire SCSI command's worth of data payload over the bulk
* pipe.
*
* No
r
e that this uses usb_stor_bulk_transfer_buf() and
* No
t
e that this uses usb_stor_bulk_transfer_buf() and
* usb_stor_bulk_transfer_sglist() to achieve its goals --
* this function simply determines whether we're going to use
* scatter-gather or not, and acts appropriately.
*/
int
usb_stor_bulk_transfer_sg
(
struct
us_data
*
us
,
unsigned
int
pipe
,
char
*
buf
,
unsigned
int
length_left
,
int
use_sg
,
int
*
residual
)
void
*
buf
,
unsigned
int
length_left
,
int
use_sg
,
int
*
residual
)
{
int
result
;
unsigned
int
partial
;
...
...
@@ -1278,7 +1256,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
(
bcb
.
Lun
>>
4
),
(
bcb
.
Lun
&
0x0F
),
le32_to_cpu
(
bcb
.
DataTransferLength
),
bcb
.
Flags
,
bcb
.
Length
);
result
=
usb_stor_bulk_transfer_buf
(
us
,
us
->
send_bulk_pipe
,
(
char
*
)
&
bcb
,
US_BULK_CB_WRAP_LEN
,
NULL
);
&
bcb
,
US_BULK_CB_WRAP_LEN
,
NULL
);
US_DEBUGP
(
"Bulk command transfer result=%d
\n
"
,
result
);
if
(
result
!=
USB_STOR_XFER_GOOD
)
return
USB_STOR_TRANSPORT_ERROR
;
...
...
@@ -1302,7 +1280,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* get CSW for device status */
US_DEBUGP
(
"Attempting to get CSW...
\n
"
);
result
=
usb_stor_bulk_transfer_buf
(
us
,
us
->
recv_bulk_pipe
,
(
char
*
)
&
bcs
,
US_BULK_CS_WRAP_LEN
,
NULL
);
&
bcs
,
US_BULK_CS_WRAP_LEN
,
NULL
);
/* did the attempt to read the CSW fail? */
if
(
result
==
USB_STOR_XFER_STALLED
)
{
...
...
@@ -1310,7 +1288,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* get the status again */
US_DEBUGP
(
"Attempting to get CSW (2nd try)...
\n
"
);
result
=
usb_stor_bulk_transfer_buf
(
us
,
us
->
recv_bulk_pipe
,
(
char
*
)
&
bcs
,
US_BULK_CS_WRAP_LEN
,
NULL
);
&
bcs
,
US_BULK_CS_WRAP_LEN
,
NULL
);
}
/* if we still have a failure at this point, we're in trouble */
...
...
drivers/usb/storage/transport.h
View file @
e0afb99e
...
...
@@ -117,6 +117,7 @@ struct bulk_cs_wrap {
/*
* usb_stor_bulk_transfer_xxx() return codes, in order of severity
*/
#define USB_STOR_XFER_GOOD 0
/* good transfer */
#define USB_STOR_XFER_SHORT 1
/* transfered less than expected */
#define USB_STOR_XFER_STALLED 2
/* endpoint stalled */
...
...
@@ -129,7 +130,14 @@ struct bulk_cs_wrap {
#define USB_STOR_TRANSPORT_GOOD 0
/* Transport good, command good */
#define USB_STOR_TRANSPORT_FAILED 1
/* Transport good, command failed */
#define USB_STOR_TRANSPORT_ERROR 2
/* Transport bad (i.e. device dead) */
#define USB_STOR_TRANSPORT_ABORTED 3
/* Transport aborted */
/*
* We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED
* return codes. But now the transport and low-level transfer routines
* treat an abort as just another error (-ENOENT for a cancelled URB).
* It is up to the invoke_transport() function to test for aborts and
* distinguish them from genuine communication errors.
*/
/*
* CBI accept device specific command
...
...
@@ -162,12 +170,12 @@ extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
u8
request
,
u8
requesttype
,
u16
value
,
u16
index
,
void
*
data
,
u16
size
);
extern
int
usb_stor_bulk_transfer_buf
(
struct
us_data
*
us
,
unsigned
int
pipe
,
char
*
buf
,
unsigned
int
length
,
unsigned
int
*
act_len
);
void
*
buf
,
unsigned
int
length
,
unsigned
int
*
act_len
);
extern
int
usb_stor_bulk_transfer_sglist
(
struct
us_data
*
us
,
unsigned
int
pipe
,
struct
scatterlist
*
sg
,
int
num_sg
,
unsigned
int
length
,
unsigned
int
*
act_len
);
extern
int
usb_stor_bulk_transfer_sg
(
struct
us_data
*
us
,
unsigned
int
pipe
,
char
*
buf
,
unsigned
int
length
,
int
use_sg
,
int
*
residual
);
void
*
buf
,
unsigned
int
length
,
int
use_sg
,
int
*
residual
);
static
__inline__
int
usb_stor_bulk_transfer_srb
(
struct
us_data
*
us
,
unsigned
int
pipe
,
Scsi_Cmnd
*
srb
,
unsigned
int
length
)
{
...
...
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