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
nexedi
linux
Commits
234d5b73
Commit
234d5b73
authored
Oct 08, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linuxusb.bkbits.net/linus-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
718443d7
1fa273f8
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
554 additions
and
60 deletions
+554
-60
MAINTAINERS
MAINTAINERS
+4
-5
drivers/base/hotplug.c
drivers/base/hotplug.c
+1
-1
drivers/media/video/cpia.h
drivers/media/video/cpia.h
+2
-2
drivers/usb/core/driverfs.c
drivers/usb/core/driverfs.c
+29
-0
drivers/usb/core/usb.c
drivers/usb/core/usb.c
+0
-8
drivers/usb/misc/usbtest.c
drivers/usb/misc/usbtest.c
+498
-43
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.c
+1
-1
include/linux/device.h
include/linux/device.h
+19
-0
No files found.
MAINTAINERS
View file @
234d5b73
...
...
@@ -1720,7 +1720,7 @@ L: linux-usb-devel@lists.sourceforge.net
W: http://www.suse.cz/development/input/
S: Maintained
USB HUB
USB HUB
DRIVER
P: Johannes Erdfelt
M: johannes@erdfelt.com
L: linux-usb-users@lists.sourceforge.net
...
...
@@ -1863,11 +1863,10 @@ W: http://www.linux-usb.org
S: Supported
USB UHCI DRIVER
P:
Georg Acher
M:
usb@in.tum.de
P:
Johannes Erdfelt
M:
johannes@erdfelt.com
L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
W: http://usb.in.tum.de
S: Maintained
USB "USBNET" DRIVER
...
...
drivers/base/hotplug.c
View file @
234d5b73
...
...
@@ -97,7 +97,7 @@ int dev_hotplug (struct device *dev, const char *action)
scratch
+=
sprintf
(
scratch
,
"ACTION=%s"
,
action
)
+
1
;
envp
[
i
++
]
=
scratch
;
scratch
+=
sprintf
(
scratch
,
"DEV
ICE
=%s"
,
dev_path
)
+
1
;
scratch
+=
sprintf
(
scratch
,
"DEV
PATH
=%s"
,
dev_path
)
+
1
;
if
(
dev
->
bus
->
hotplug
)
{
/* have the bus specific function add its stuff */
...
...
drivers/media/video/cpia.h
View file @
234d5b73
...
...
@@ -378,8 +378,8 @@ void cpia_unregister_camera(struct cam_data *cam);
/* ErrorCode */
#define ERROR_FLICKER_BELOW_MIN_EXP 0x01
/*flicker exposure got below minimum exposure */
#define ALOG(
lineno,fmt,args...) printk(fmt,lineno,
##args)
#define LOG(fmt,args...) ALOG(
(__LINE__),KERN_INFO __FILE__":%s(%d):"fmt, __FUNCTION
__, ##args)
#define ALOG(
fmt,args...) printk(fmt,
##args)
#define LOG(fmt,args...) ALOG(
KERN_INFO __FILE__ ":%s(%d):" fmt, __FUNCTION__, __LINE
__, ##args)
#ifdef _CPIA_DEBUG_
#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, lineno, ##args)
...
...
drivers/usb/core/driverfs.c
View file @
234d5b73
...
...
@@ -99,6 +99,34 @@ show_serial (struct device *dev, char *buf, size_t count, loff_t off)
}
static
DEVICE_ATTR
(
serial
,
S_IRUGO
,
show_serial
,
NULL
);
static
ssize_t
show_speed
(
struct
device
*
dev
,
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
usb_device
*
udev
;
char
*
speed
;
if
(
off
)
return
0
;
udev
=
to_usb_device
(
dev
);
switch
(
udev
->
speed
)
{
case
USB_SPEED_LOW
:
speed
=
"1.5"
;
break
;
case
USB_SPEED_UNKNOWN
:
case
USB_SPEED_FULL
:
speed
=
"12"
;
break
;
case
USB_SPEED_HIGH
:
speed
=
"480"
;
break
;
default:
speed
=
"unknown"
;
}
return
sprintf
(
buf
,
"%s
\n
"
,
speed
);
}
static
DEVICE_ATTR
(
speed
,
S_IRUGO
,
show_speed
,
NULL
);
/* Descriptor fields */
#define usb_descriptor_attr(field, format_string) \
static ssize_t \
...
...
@@ -136,6 +164,7 @@ void usb_create_driverfs_dev_files (struct usb_device *udev)
device_create_file
(
dev
,
&
dev_attr_bDeviceClass
);
device_create_file
(
dev
,
&
dev_attr_bDeviceSubClass
);
device_create_file
(
dev
,
&
dev_attr_bDeviceProtocol
);
device_create_file
(
dev
,
&
dev_attr_speed
);
if
(
udev
->
descriptor
.
iManufacturer
)
device_create_file
(
dev
,
&
dev_attr_manufacturer
);
...
...
drivers/usb/core/usb.c
View file @
234d5b73
...
...
@@ -556,14 +556,6 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
*
* FIXME reduce hardwired intelligence here
*/
envp
[
i
++
]
=
scratch
;
length
+=
snprintf
(
scratch
,
buffer_size
-
length
,
"%s"
,
"DEVFS=/proc/bus/usb"
);
if
((
buffer_size
-
length
<=
0
)
||
(
i
>=
num_envp
))
return
-
ENOMEM
;
++
length
;
scratch
+=
length
;
envp
[
i
++
]
=
scratch
;
length
+=
snprintf
(
scratch
,
buffer_size
-
length
,
"DEVICE=/proc/bus/usb/%03d/%03d"
,
...
...
drivers/usb/misc/usbtest.c
View file @
234d5b73
...
...
@@ -5,7 +5,6 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/module.h>
//#include <linux/time.h>
#include <asm/scatterlist.h>
#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
...
...
@@ -33,21 +32,43 @@ struct usbtest_param {
/*-------------------------------------------------------------------------*/
#define GENERIC
/* let probe() bind using module params */
/* Some devices that can be used for testing will have "real" drivers.
* Entries for those need to be enabled here by hand, after disabling
* that "real" driver.
*/
//#define IBOT2 /* grab iBOT2 webcams */
//#define KEYSPAN_19Qi /* grab un-renumerated serial adapter */
/*-------------------------------------------------------------------------*/
struct
usbtest_info
{
const
char
*
name
;
u8
ep_in
;
/* bulk/intr source */
u8
ep_out
;
/* bulk/intr sink */
int
alt
;
};
/* this is accessed only through usbfs ioctl calls.
* one ioctl to issue a test ... no locking needed!!!
* tests create other threads if they need them.
* urbs and buffers are allocated dynamically,
* and data generated deterministically.
*
* there's a minor complication on
disconnect()
, since
* there's a minor complication on
rmmod
, since
* usbfs.disconnect() waits till our ioctl completes.
* unplug works fine since we'll see real i/o errors.
*/
struct
usbtest_dev
{
struct
usb_interface
*
intf
;
struct
testdev
_info
*
info
;
struct
usbtest
_info
*
info
;
char
id
[
32
];
int
in_pipe
;
int
out_pipe
;
#define TBUF_SIZE 256
u8
*
buf
;
};
static
struct
usb_device
*
testdev_to_usbdev
(
struct
usbtest_dev
*
test
)
...
...
@@ -90,6 +111,8 @@ static struct urb *simple_alloc_urb (
?
(
INTERRUPT_RATE
<<
3
)
:
INTERRUPT_RATE
,
urb
->
transfer_flags
=
URB_NO_DMA_MAP
;
if
(
usb_pipein
(
pipe
))
urb
->
transfer_flags
|=
URB_SHORT_NOT_OK
;
urb
->
transfer_buffer
=
usb_buffer_alloc
(
udev
,
bytes
,
SLAB_KERNEL
,
&
urb
->
transfer_dma
);
if
(
!
urb
->
transfer_buffer
)
{
...
...
@@ -245,6 +268,279 @@ static int perform_sglist (
}
/*-------------------------------------------------------------------------*/
/* unqueued control message testing
*
* there's a nice set of device functional requirements in chapter 9 of the
* usb 2.0 spec, which we can apply to ANY device, even ones that don't use
* special test firmware.
*
* we know the device is configured (or suspended) by the time it's visible
* through usbfs. we can't change that, so we won't test enumeration (which
* worked 'well enough' to get here, this time), power management (ditto),
* or remote wakeup (which needs human interaction).
*/
static
int
get_altsetting
(
struct
usbtest_dev
*
dev
)
{
struct
usb_interface
*
iface
=
dev
->
intf
;
struct
usb_device
*
udev
=
interface_to_usbdev
(
iface
);
int
retval
;
retval
=
usb_control_msg
(
udev
,
usb_rcvctrlpipe
(
udev
,
0
),
USB_REQ_GET_INTERFACE
,
USB_DIR_IN
|
USB_RECIP_INTERFACE
,
0
,
iface
->
altsetting
[
0
].
bInterfaceNumber
,
dev
->
buf
,
1
,
HZ
*
USB_CTRL_GET_TIMEOUT
);
switch
(
retval
)
{
case
1
:
return
dev
->
buf
[
0
];
case
0
:
retval
=
-
ERANGE
;
// FALLTHROUGH
default:
return
retval
;
}
}
/* this is usb_set_interface(), with no 'only one altsetting' case */
static
int
set_altsetting
(
struct
usbtest_dev
*
dev
,
int
alternate
)
{
struct
usb_interface
*
iface
=
dev
->
intf
;
struct
usb_device
*
udev
;
struct
usb_interface_descriptor
*
iface_as
;
int
i
,
ret
;
if
(
alternate
<
0
||
alternate
>=
iface
->
num_altsetting
)
return
-
EINVAL
;
udev
=
interface_to_usbdev
(
iface
);
if
((
ret
=
usb_control_msg
(
udev
,
usb_sndctrlpipe
(
udev
,
0
),
USB_REQ_SET_INTERFACE
,
USB_RECIP_INTERFACE
,
iface
->
altsetting
[
alternate
].
bAlternateSetting
,
iface
->
altsetting
[
alternate
].
bInterfaceNumber
,
NULL
,
0
,
HZ
*
USB_CTRL_SET_TIMEOUT
))
<
0
)
return
ret
;
// FIXME usbcore should be more like this:
// - remove that special casing in usbcore.
// - fix usbcore signature to take interface
/* prevent requests using previous endpoint settings */
iface_as
=
iface
->
altsetting
+
iface
->
act_altsetting
;
for
(
i
=
0
;
i
<
iface_as
->
bNumEndpoints
;
i
++
)
{
u8
ep
=
iface_as
->
endpoint
[
i
].
bEndpointAddress
;
int
out
=
!
(
ep
&
USB_DIR_IN
);
ep
&=
USB_ENDPOINT_NUMBER_MASK
;
(
out
?
udev
->
epmaxpacketout
:
udev
->
epmaxpacketin
)
[
ep
]
=
0
;
// FIXME want hcd hook here, "forget this endpoint"
}
iface
->
act_altsetting
=
alternate
;
/* reset toggles and maxpacket for all endpoints affected */
iface_as
=
iface
->
altsetting
+
iface
->
act_altsetting
;
for
(
i
=
0
;
i
<
iface_as
->
bNumEndpoints
;
i
++
)
{
u8
ep
=
iface_as
->
endpoint
[
i
].
bEndpointAddress
;
int
out
=
!
(
ep
&
USB_DIR_IN
);
ep
&=
USB_ENDPOINT_NUMBER_MASK
;
usb_settoggle
(
udev
,
ep
,
out
,
0
);
(
out
?
udev
->
epmaxpacketout
:
udev
->
epmaxpacketin
)
[
ep
]
=
iface_as
->
endpoint
[
ep
].
wMaxPacketSize
;
}
return
0
;
}
static
int
is_good_config
(
char
*
buf
,
int
len
)
{
struct
usb_config_descriptor
*
config
;
if
(
len
<
sizeof
*
config
)
return
0
;
config
=
(
struct
usb_config_descriptor
*
)
buf
;
switch
(
config
->
bDescriptorType
)
{
case
USB_DT_CONFIG
:
case
USB_DT_OTHER_SPEED_CONFIG
:
if
(
config
->
bLength
!=
9
)
return
0
;
#if 0
/* this bit 'must be 1' but often isn't */
if (!(config->bmAttributes & 0x80)) {
dbg ("high bit of config attributes not set");
return 0;
}
#endif
if
(
config
->
bmAttributes
&
0x1f
)
/* reserved == 0 */
return
0
;
break
;
default:
return
0
;
}
le32_to_cpus
(
&
config
->
wTotalLength
);
if
(
config
->
wTotalLength
==
len
)
/* read it all */
return
1
;
return
config
->
wTotalLength
>=
TBUF_SIZE
;
/* max partial read */
}
/* sanity test for standard requests working with usb_control_mesg() and some
* of the utility functions which use it.
*
* this doesn't test how endpoint halts behave or data toggles get set, since
* we won't do I/O to bulk/interrupt endpoints here (which is how to change
* halt or toggle). toggle testing is impractical without support from hcds.
*
* this avoids failing devices linux would normally work with, by not testing
* config/altsetting operations for devices that only support their defaults.
* such devices rarely support those needless operations.
*
* NOTE that since this is a sanity test, it's not examining boundary cases
* to see if usbcore, hcd, and device all behave right. such testing would
* involve varied read sizes and other operation sequences.
*/
static
int
ch9_postconfig
(
struct
usbtest_dev
*
dev
)
{
struct
usb_interface
*
iface
=
dev
->
intf
;
struct
usb_device
*
udev
=
interface_to_usbdev
(
iface
);
int
i
,
retval
;
/* [9.2.3] if there's more than one altsetting, we need to be able to
* set and get each one. mostly trusts the descriptors from usbcore.
*/
for
(
i
=
0
;
i
<
iface
->
num_altsetting
;
i
++
)
{
/* 9.2.3 constrains the range here, and Linux ensures
* they're ordered meaningfully in this array
*/
if
(
iface
->
altsetting
[
i
].
bAlternateSetting
!=
i
)
{
dbg
(
"%s, illegal alt [%d].bAltSetting = %d"
,
dev
->
id
,
i
,
iface
->
altsetting
[
i
]
.
bAlternateSetting
);
return
-
EDOM
;
}
/* [real world] get/set unimplemented if there's only one */
if
(
iface
->
num_altsetting
==
1
)
continue
;
/* [9.4.10] set_interface */
retval
=
set_altsetting
(
dev
,
i
);
if
(
retval
)
{
dbg
(
"%s can't set_interface = %d, %d"
,
dev
->
id
,
i
,
retval
);
return
retval
;
}
/* [9.4.4] get_interface always works */
retval
=
get_altsetting
(
dev
);
if
(
retval
!=
i
)
{
dbg
(
"%s get alt should be %d, was %d"
,
dev
->
id
,
i
,
retval
);
return
(
retval
<
0
)
?
retval
:
-
EDOM
;
}
}
/* [real world] get_config unimplemented if there's only one */
if
(
udev
->
descriptor
.
bNumConfigurations
!=
1
)
{
int
expected
=
udev
->
actconfig
->
bConfigurationValue
;
/* [9.4.2] get_configuration always works */
retval
=
usb_control_msg
(
udev
,
usb_rcvctrlpipe
(
udev
,
0
),
USB_REQ_GET_CONFIGURATION
,
USB_RECIP_DEVICE
,
0
,
0
,
dev
->
buf
,
1
,
HZ
*
USB_CTRL_GET_TIMEOUT
);
if
(
retval
!=
1
||
dev
->
buf
[
0
]
!=
expected
)
{
dbg
(
"%s get config --> %d (%d)"
,
dev
->
id
,
retval
,
expected
);
return
(
retval
<
0
)
?
retval
:
-
EDOM
;
}
}
/* there's always [9.4.3] a device descriptor [9.6.1] */
retval
=
usb_get_descriptor
(
udev
,
USB_DT_DEVICE
,
0
,
dev
->
buf
,
sizeof
udev
->
descriptor
);
if
(
retval
!=
sizeof
udev
->
descriptor
)
{
dbg
(
"%s dev descriptor --> %d"
,
dev
->
id
,
retval
);
return
(
retval
<
0
)
?
retval
:
-
EDOM
;
}
/* there's always [9.4.3] at least one config descriptor [9.6.3] */
for
(
i
=
0
;
i
<
udev
->
descriptor
.
bNumConfigurations
;
i
++
)
{
retval
=
usb_get_descriptor
(
udev
,
USB_DT_CONFIG
,
i
,
dev
->
buf
,
TBUF_SIZE
);
if
(
!
is_good_config
(
dev
->
buf
,
retval
))
{
dbg
(
"%s config [%d] descriptor --> %d"
,
dev
->
id
,
i
,
retval
);
return
(
retval
<
0
)
?
retval
:
-
EDOM
;
}
// FIXME cross-checking udev->config[i] to make sure usbcore
// parsed it right (etc) would be good testing paranoia
}
/* and sometimes [9.2.6.6] speed dependent descriptors */
if
(
udev
->
descriptor
.
bcdUSB
==
0x0200
)
{
/* pre-swapped */
struct
usb_qualifier_descriptor
*
d
=
0
;
/* device qualifier [9.6.2] */
retval
=
usb_get_descriptor
(
udev
,
USB_DT_DEVICE_QUALIFIER
,
0
,
dev
->
buf
,
sizeof
(
struct
usb_qualifier_descriptor
));
if
(
retval
==
-
EPIPE
)
{
if
(
udev
->
speed
==
USB_SPEED_HIGH
)
{
dbg
(
"%s hs dev qualifier --> %d"
,
dev
->
id
,
retval
);
return
(
retval
<
0
)
?
retval
:
-
EDOM
;
}
/* usb2.0 but not high-speed capable; fine */
}
else
if
(
retval
!=
sizeof
(
struct
usb_qualifier_descriptor
))
{
dbg
(
"%s dev qualifier --> %d"
,
dev
->
id
,
retval
);
return
(
retval
<
0
)
?
retval
:
-
EDOM
;
}
else
d
=
(
struct
usb_qualifier_descriptor
*
)
dev
->
buf
;
/* might not have [9.6.2] any other-speed configs [9.6.4] */
if
(
d
)
{
unsigned
max
=
d
->
bNumConfigurations
;
for
(
i
=
0
;
i
<
max
;
i
++
)
{
retval
=
usb_get_descriptor
(
udev
,
USB_DT_OTHER_SPEED_CONFIG
,
i
,
dev
->
buf
,
TBUF_SIZE
);
if
(
!
is_good_config
(
dev
->
buf
,
retval
))
{
dbg
(
"%s other speed config --> %d"
,
dev
->
id
,
retval
);
return
(
retval
<
0
)
?
retval
:
-
EDOM
;
}
}
}
}
// FIXME fetch strings from at least the device descriptor
/* [9.4.5] get_status always works */
retval
=
usb_get_status
(
udev
,
USB_RECIP_DEVICE
,
0
,
dev
->
buf
);
if
(
retval
!=
2
)
{
dbg
(
"%s get dev status --> %d"
,
dev
->
id
,
retval
);
return
(
retval
<
0
)
?
retval
:
-
EDOM
;
}
// FIXME configuration.bmAttributes says if we could try to set/clear
// the device's remote wakeup feature ... if we can, test that here
retval
=
usb_get_status
(
udev
,
USB_RECIP_INTERFACE
,
iface
->
altsetting
[
0
].
bInterfaceNumber
,
dev
->
buf
);
if
(
retval
!=
2
)
{
dbg
(
"%s get interface status --> %d"
,
dev
->
id
,
retval
);
return
(
retval
<
0
)
?
retval
:
-
EDOM
;
}
// FIXME get status for each endpoint in the interface
return
0
;
}
/*-------------------------------------------------------------------------*/
/* We only have this one interface to user space, through usbfs.
...
...
@@ -270,6 +566,7 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b
struct
scatterlist
*
sg
;
struct
usb_sg_request
req
;
struct
timeval
start
;
unsigned
i
;
// FIXME USBDEVFS_CONNECTINFO doesn't say how fast the device is.
...
...
@@ -280,6 +577,23 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b
||
param
->
sglen
<
0
||
param
->
vary
<
0
)
return
-
EINVAL
;
/* some devices, like ez-usb default devices, need a non-default
* altsetting to have any active endpoints. some tests change
* altsettings; force a default so most tests don't need to check.
*/
if
(
dev
->
info
->
alt
>=
0
)
{
int
res
;
if
(
intf
->
altsetting
->
bInterfaceNumber
)
return
-
ENODEV
;
res
=
set_altsetting
(
dev
,
dev
->
info
->
alt
);
if
(
res
)
{
err
(
"%s: set altsetting to %d failed, %d"
,
dev
->
id
,
dev
->
info
->
alt
,
res
);
return
res
;
}
}
/*
* Just a bunch of test cases that every HCD is expected to handle.
*
...
...
@@ -287,7 +601,7 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b
* one firmware image to handle all the test cases.
*
* FIXME add more tests! cancel requests, verify the data, control
*
request
s, and so on.
*
queueing, concurrent read+write thread
s, and so on.
*/
do_gettimeofday
(
&
start
);
switch
(
param
->
test_num
)
{
...
...
@@ -343,7 +657,7 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b
case
4
:
if
(
dev
->
in_pipe
==
0
||
param
->
vary
==
0
)
break
;
dbg
(
"%s TEST
3
: read/%d 0..%d bytes %u times"
,
dev
->
id
,
dbg
(
"%s TEST
4
: read/%d 0..%d bytes %u times"
,
dev
->
id
,
param
->
vary
,
param
->
length
,
param
->
iterations
);
urb
=
simple_alloc_urb
(
udev
,
dev
->
out_pipe
,
param
->
length
);
if
(
!
urb
)
{
...
...
@@ -422,6 +736,17 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b
free_sglist
(
sg
,
param
->
sglen
);
break
;
/* non-queued sanity tests for control (chapter 9 subset) */
case
9
:
retval
=
0
;
dbg
(
"%s TEST 9: ch9 (subset) control tests, %d times"
,
dev
->
id
,
param
->
iterations
);
for
(
i
=
param
->
iterations
;
retval
==
0
&&
i
--
;
/* NOP */
)
retval
=
ch9_postconfig
(
dev
);
if
(
retval
)
dbg
(
"ch9 subset failed, iterations left %d"
,
i
);
break
;
/* test cases for the unlink/cancel codepaths need a thread to
* usb_unlink_urb() or usg_sg_cancel(), and a way to check if
* the urb/sg_request was properly canceled.
...
...
@@ -443,48 +768,77 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b
/*-------------------------------------------------------------------------*/
/* most programmable USB devices can be given firmware that will support the
* test cases above. one basic question is which endpoints to use for
* testing; endpoint numbers are not always firmware-selectable.
*
* for now, the driver_info in the device_id table entry just encodes the
* endpoint info for a pair of bulk-capable endpoints, which we can use
* for some interrupt transfer tests too. later this could get fancier.
*/
#define EP_PAIR(in,out) (((in)<<4)|(out))
static
int
force_interrupt
=
0
;
MODULE_PARM
(
force_interrupt
,
"i"
);
MODULE_PARM_DESC
(
force_interrupt
,
"0 = test bulk (default), else interrupt"
);
#ifdef GENERIC
static
int
vendor
;
MODULE_PARM
(
vendor
,
"h"
);
MODULE_PARM_DESC
(
vendor
,
"vendor code (from usb-if)"
);
static
int
product
;
MODULE_PARM
(
product
,
"h"
);
MODULE_PARM_DESC
(
product
,
"product code (from vendor)"
);
#endif
static
int
usbtest_probe
(
struct
usb_interface
*
intf
,
const
struct
usb_device_id
*
id
)
{
struct
usb_device
*
udev
;
struct
usbtest_dev
*
dev
;
unsigned
long
driver_info
=
id
->
driver_info
;
struct
usbtest_info
*
info
;
char
*
rtest
,
*
wtest
;
udev
=
interface_to_usbdev
(
intf
);
#ifdef GENERIC
/* specify devices by module parameters? */
if
(
id
->
match_flags
==
0
)
{
/* vendor match required, product match optional */
if
(
!
vendor
||
udev
->
descriptor
.
idVendor
!=
(
u16
)
vendor
)
return
-
ENODEV
;
if
(
product
&&
udev
->
descriptor
.
idProduct
!=
(
u16
)
product
)
return
-
ENODEV
;
dbg
(
"matched module params, vend=0x%04x prod=0x%04x"
,
udev
->
descriptor
.
idVendor
,
udev
->
descriptor
.
idProduct
);
}
#endif
dev
=
kmalloc
(
sizeof
*
dev
,
SLAB_KERNEL
);
if
(
!
dev
)
return
-
ENOMEM
;
memset
(
dev
,
0
,
sizeof
*
dev
);
snprintf
(
dev
->
id
,
sizeof
dev
->
id
,
"%s-%s"
,
udev
->
bus
->
bus_name
,
udev
->
devpath
);
info
=
(
struct
usbtest_info
*
)
id
->
driver_info
;
dev
->
info
=
info
;
/* use the same kind of id the hid driver shows */
snprintf
(
dev
->
id
,
sizeof
dev
->
id
,
"%s-%s:%d"
,
udev
->
bus
->
bus_name
,
udev
->
devpath
,
intf
->
altsetting
[
0
].
bInterfaceNumber
);
dev
->
intf
=
intf
;
/* cacheline-aligned scratch for i/o */
if
((
dev
->
buf
=
kmalloc
(
TBUF_SIZE
,
SLAB_KERNEL
))
==
0
)
{
kfree
(
dev
);
return
-
ENOMEM
;
}
/* NOTE this doesn't yet test the handful of difference that are
* visible with high speed
device
s: bigger maxpacket (1K) and
* visible with high speed
interrupt
s: bigger maxpacket (1K) and
* "high bandwidth" modes (up to 3 packets/uframe).
*/
rtest
=
wtest
=
""
;
if
(
force_interrupt
||
udev
->
speed
==
USB_SPEED_LOW
)
{
if
(
driver_info
&
0xf0
)
dev
->
in_pipe
=
usb_rcvintpipe
(
udev
,
(
driver_info
>>
4
)
&
0x0f
);
if
(
driver_info
&
0x0f
)
dev
->
out_pipe
=
usb_sndintpipe
(
udev
,
driver_info
&
0x0f
);
if
(
info
->
ep_in
)
{
dev
->
in_pipe
=
usb_rcvintpipe
(
udev
,
info
->
ep_in
);
rtest
=
" intr-in"
;
}
if
(
info
->
ep_out
)
{
dev
->
out_pipe
=
usb_sndintpipe
(
udev
,
info
->
ep_out
);
wtest
=
" intr-out"
;
}
#if 1
// FIXME disabling this until we finally get rid of
...
...
@@ -494,18 +848,26 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id)
return
-
ENODEV
;
#endif
}
else
{
if
(
driver_info
&
0xf0
)
dev
->
in_pipe
=
usb_rcvbulkpipe
(
udev
,
(
driver_info
>>
4
)
&
0x0f
);
if
(
driver_info
&
0x0f
)
dev
->
out_pipe
=
usb_sndbulkpipe
(
udev
,
driver_info
&
0x0f
);
if
(
info
->
ep_in
)
{
dev
->
in_pipe
=
usb_rcvbulkpipe
(
udev
,
info
->
ep_in
);
rtest
=
" bulk-in"
;
}
if
(
info
->
ep_out
)
{
dev
->
out_pipe
=
usb_sndbulkpipe
(
udev
,
info
->
ep_out
);
wtest
=
" bulk-out"
;
}
}
dev_set_drvdata
(
&
intf
->
dev
,
dev
);
info
(
"bound to %s ...%s%s"
,
dev
->
id
,
dev
->
out_pipe
?
" writes"
:
""
,
dev
->
in_pipe
?
" reads"
:
""
);
info
(
"%s at %s ... %s speed {control%s%s} tests"
,
info
->
name
,
dev
->
id
,
({
char
*
tmp
;
switch
(
udev
->
speed
)
{
case
USB_SPEED_LOW
:
tmp
=
"low"
;
break
;
case
USB_SPEED_FULL
:
tmp
=
"full"
;
break
;
case
USB_SPEED_HIGH
:
tmp
=
"high"
;
break
;
default:
tmp
=
"unknown"
;
break
;
};
tmp
;
}),
rtest
,
wtest
);
return
0
;
}
...
...
@@ -519,24 +881,113 @@ static void usbtest_disconnect (struct usb_interface *intf)
}
/* Basic testing only needs a device that can source or sink bulk traffic.
* Any device can test control transfers (default with GENERIC binding).
*
* Several entries work with the default EP0 implementation that's built
* into EZ-USB chips. There's a default vendor ID which can be overridden
* by (very) small config EEPROMS, but otherwise all these devices act
* identically until firmware is loaded: only EP0 works. It turns out
* to be easy to make other endpoints work, without modifying that EP0
* behavior. For now, we expect that kind of firmware.
*/
static
struct
usb_device_id
id_table
[]
=
{
/* EZ-USB FX2 "bulksrc" or "bulkloop" firmware from Cypress
* reads disabled on this one, my version has some problem there
/* an21xx or fx versions of ez-usb */
static
struct
usbtest_info
ez1_info
=
{
.
name
=
"EZ-USB device"
,
.
ep_in
=
2
,
.
ep_out
=
2
,
.
alt
=
1
,
};
/* fx2 version of ez-usb */
static
struct
usbtest_info
ez2_info
=
{
.
name
=
"FX2 device"
,
.
ep_in
=
6
,
.
ep_out
=
2
,
.
alt
=
1
,
};
#ifdef IBOT2
/* this is a nice source of high speed bulk data;
* uses an FX2, with firmware provided in the device
*/
static
struct
usbtest_info
ibot2_info
=
{
.
name
=
"iBOT2 webcam"
,
.
ep_in
=
2
,
.
alt
=
-
1
,
};
#endif
#ifdef GENERIC
/* we can use any device to test control traffic */
static
struct
usbtest_info
generic_info
=
{
.
name
=
"Generic USB device"
,
.
alt
=
-
1
,
};
#endif
// FIXME remove this
static
struct
usbtest_info
hact_info
=
{
.
name
=
"FX2/hact"
,
//.ep_in = 6,
.
ep_out
=
2
,
.
alt
=
-
1
,
};
static
struct
usb_device_id
id_table
[]
=
{
{
USB_DEVICE
(
0x0547
,
0x1002
),
.
driver_info
=
EP_PAIR
(
0
,
2
)
,
.
driver_info
=
(
unsigned
long
)
&
hact_info
,
},
#if 1
/*-------------------------------------------------------------*/
/* EZ-USB devices which download firmware to replace (or in our
* case augment) the default device implementation.
*/
/* generic EZ-USB FX controller */
{
USB_DEVICE
(
0x0547
,
0x2235
),
.
driver_info
=
(
unsigned
long
)
&
ez1_info
,
},
/* CY3671 development board with EZ-USB FX */
{
USB_DEVICE
(
0x0547
,
0x0080
),
.
driver_info
=
(
unsigned
long
)
&
ez1_info
,
},
/* generic EZ-USB FX2 controller (or development board) */
{
USB_DEVICE
(
0x04b4
,
0x8613
),
.
driver_info
=
(
unsigned
long
)
&
ez2_info
,
},
#ifdef KEYSPAN_19Qi
/* Keyspan 19qi uses an21xx (original EZ-USB) */
// this does not coexist with the real Keyspan 19qi driver!
{
USB_DEVICE
(
0x06cd
,
0x010b
),
.
driver_info
=
(
unsigned
long
)
&
ez1_info
,
},
#endif
/*-------------------------------------------------------------*/
#ifdef IBOT2
/* iBOT2 makes a nice source of high speed bulk-in data */
// this does not coexist with a real iBOT2 driver!
// it makes a nice source of high speed bulk-in data
{
USB_DEVICE
(
0x0b62
,
0x0059
),
.
driver_info
=
EP_PAIR
(
2
,
0
)
,
.
driver_info
=
(
unsigned
long
)
&
ibot2_info
,
},
#endif
/* can that old "usbstress-0.3" firmware be used with this? */
/*-------------------------------------------------------------*/
#ifdef GENERIC
/* module params can specify devices to use for control tests */
{
.
driver_info
=
(
unsigned
long
)
&
generic_info
,
},
#endif
/*-------------------------------------------------------------*/
{
}
};
...
...
@@ -555,6 +1006,10 @@ static struct usb_driver usbtest_driver = {
static
int
__init
usbtest_init
(
void
)
{
#ifdef GENERIC
if
(
vendor
)
dbg
(
"params: vend=0x%04x prod=0x%04x"
,
vendor
,
product
);
#endif
return
usb_register
(
&
usbtest_driver
);
}
module_init
(
usbtest_init
);
...
...
@@ -565,6 +1020,6 @@ static void __exit usbtest_exit (void)
}
module_exit
(
usbtest_exit
);
MODULE_DESCRIPTION
(
"USB HCD Testing Driver"
);
MODULE_DESCRIPTION
(
"USB
Core/
HCD Testing Driver"
);
MODULE_LICENSE
(
"GPL"
);
drivers/usb/serial/pl2303.c
View file @
234d5b73
...
...
@@ -358,7 +358,7 @@ static void pl2303_set_termios (struct usb_serial_port *port, struct termios *ol
if
(
cflag
&
CRTSCTS
)
{
i
=
usb_control_msg
(
serial
->
dev
,
usb_sndctrlpipe
(
serial
->
dev
,
0
),
VENDOR_WRITE_REQUEST
_TYPE
,
VENDOR_WRITE_REQUEST_TYPE
,
VENDOR_WRITE_REQUEST
,
VENDOR_WRITE_REQUEST_TYPE
,
0x0
,
0x41
,
NULL
,
0
,
100
);
dbg
(
"0x40:0x1:0x0:0x41 %d"
,
i
);
}
...
...
include/linux/device.h
View file @
234d5b73
...
...
@@ -421,4 +421,23 @@ extern int device_suspend(u32 state, u32 level);
extern
void
device_resume
(
u32
level
);
extern
void
device_shutdown
(
void
);
/* debugging and troubleshooting/diagnostic helpers. */
#ifdef DEBUG
#define dev_dbg(dev, format, arg...) \
printk (KERN_DEBUG "%s %s: " format , \
dev.driver->name , dev.bus_id , ## arg)
#else
#define dev_dbg(dev, format, arg...) do {} while (0)
#endif
#define dev_err(dev, format, arg...) \
printk (KERN_ERR "%s %s: " format , \
dev.driver->name , dev.bus_id , ## arg)
#define dev_info(dev, format, arg...) \
printk (KERN_INFO "%s %s: " format , \
dev.driver->name , dev.bus_id , ## arg)
#define dev_warn(dev, format, arg...) \
printk (KERN_WARN "%s %s: " format , \
dev.driver->name , dev.bus_id , ## arg)
#endif
/* _DEVICE_H_ */
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