Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Kirill Smelkov
linux
Commits
1a11f106
Commit
1a11f106
authored
21 years ago
by
Greg Kroah-Hartman
Browse files
Options
Download
Plain Diff
merge
parents
3f69168f
9616878a
Changes
70
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
715 additions
and
115 deletions
+715
-115
CREDITS
CREDITS
+8
-1
Documentation/usb/w9968cf.txt
Documentation/usb/w9968cf.txt
+463
-0
MAINTAINERS
MAINTAINERS
+7
-0
drivers/usb/Makefile
drivers/usb/Makefile
+1
-1
drivers/usb/class/audio.h
drivers/usb/class/audio.h
+0
-6
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-acm.c
+30
-12
drivers/usb/class/usb-midi.h
drivers/usb/class/usb-midi.h
+0
-6
drivers/usb/class/usblp.c
drivers/usb/class/usblp.c
+8
-6
drivers/usb/core/hcd.c
drivers/usb/core/hcd.c
+7
-1
drivers/usb/core/hub.c
drivers/usb/core/hub.c
+20
-9
drivers/usb/core/hub.h
drivers/usb/core/hub.h
+2
-0
drivers/usb/core/message.c
drivers/usb/core/message.c
+6
-1
drivers/usb/core/usb.c
drivers/usb/core/usb.c
+49
-30
drivers/usb/host/ohci-dbg.c
drivers/usb/host/ohci-dbg.c
+25
-18
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-hcd.c
+4
-4
drivers/usb/host/ohci-q.c
drivers/usb/host/ohci-q.c
+24
-8
drivers/usb/host/ohci.h
drivers/usb/host/ohci.h
+8
-2
drivers/usb/image/scanner.c
drivers/usb/image/scanner.c
+4
-0
drivers/usb/image/scanner.h
drivers/usb/image/scanner.h
+14
-3
drivers/usb/media/Kconfig
drivers/usb/media/Kconfig
+35
-7
No files found.
CREDITS
View file @
1a11f106
...
...
@@ -2669,6 +2669,13 @@ S: Kasarmikatu 11 A4
S: 70110 Kuopio
S: Finland
N: Luca Risolia
E: luca_ing@libero.it
D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chip
S: Via Libertà 41/a
S: Osio Sotto, 24046, Bergamo
S: Italy
N: William E. Roadcap
E: roadcapw@cfw.com
W: http://www.cfw.com/~roadcapw
...
...
@@ -3569,4 +3576,4 @@ S: France
# alphabetically. Leonard used to be very proud of being the
# last entry, and he'll get positively pissed if he can't even
# be second-to-last. (and this file really _is_ supposed to be
# in alphabetic order)
# in alphabetic order)
This diff is collapsed.
Click to expand it.
Documentation/usb/w9968cf.txt
0 → 100644
View file @
1a11f106
W996[87]CF JPEG USB Dual Mode Camera Chip driver for Linux 2.6
==============================================================
- Documentation -
Index
=====
1. Copyright
2. License
3. Overview
4. Supported devices
5. Kernel configuration and third-part module compilation
6. Module loading
7. Module paramaters
8. Credits
1. Copyright
============
Copyright (C) 2002 2003 by Luca Risolia <luca_ing@libero.it>
2. License
==========
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
3. Overview
===========
This driver supports the video streaming capabilities of the devices mounting
Winbond W9967CF and Winbond W9968CF JPEG USB Dual Mode Camera Chips, when they
are being commanded by USB.
The driver relies on the Video4Linux, USB and I2C core modules of the Linux
kernel, version 2.6.0 or greater, and is not compatible in any way with
previous versions. It has been designed to run properly on SMP systems
as well. At the moment, an additional module, "ovcamchip", is mandatory; it
provides support for some OmniVision CMOS sensors connected to the W996[87]CF
chips.
The driver is split into two modules: the basic one, "w9968cf", is needed for
the supported devices to work; the second one, "w9968cf-vpp", is an optional
module, which provides some useful video post-processing functions like video
decoding, up-scaling and colour conversions. These routines can't be included
into official kernels for performance purposes. Once the driver is installed,
every time an application tries to open a recognized device, "w9968cf" checks
the presence of the "w9968cf-vpp" module and loads it automatically by default.
Up to 32 cameras can be handled at the same time. They can be connected and
disconnected from the host many times without turning off the computer, if
your system supports the hotplug facility.
To change the default settings for each camera, many paramaters can be passed
through command line when the module is loaded into memory.
The latest and full featured version of the W996[87]CF driver can be found at:
http://go.lamarinapunto.com/
The "ovcamchip" module is part of the OV511 driver, version 2.25, which can be
downloaded from internet:
http://alpha.dyndns.org/ov511/
To know how to patch, compile and load it, read the paragraphs below.
4. Supported devices
====================
At the moment, known W996[87]CF based devices are:
- Aroma Digi Pen ADG-5000 Refurbished
- AVerTV USB
- Creative Labs Video Blaster WebCam Go
- Creative Labs Video Blaster WebCam Go Plus
- Die Lebon LDC-D35A Digital Kamera
- Ezonics EZ-802 EZMega Cam
- OPCOM Digi Pen VGA Dual Mode Pen Camera
If you know any other W996[87]CF based cameras, please contact me.
The list above does NOT imply that all those devices work with this driver: up
until now only webcams that have a CMOS sensor supported by the "ovcamchip"
module work.
For a list of supported CMOS sensors, please visit the module author homepage:
http://alpha.dyndns.org/ov511/
Possible external microcontrollers of those webcams are not supported: this
means that still images can't be downloaded from the device memory.
Furthermore, it's worth to note that I was only able to run tests on my
"Creative Labs Video Blaster WebCam Go". Donations of other models, for
additional testing and full support, would be much appreciated.
5. Kernel configuration and third-part module compilation
=========================================================
As noted above, kernel 2.6.0 is the minimum for this driver; for it to work
properly, the driver needs kernel support for Video4Linux, USB and I2C, and a
third-part module for the CMOS sensor.
The following options of the kernel configuration file must be enabled and
corresponding modules must be compiled:
# Multimedia devices
#
CONFIG_VIDEO_DEV=m
# I2C support
#
CONFIG_I2C=m
The I2C core module can be compiled statically in the kernel as well.
# USB support
#
CONFIG_USB=m
In addition, depending on the hardware being used, just one of the modules
below is necessary:
# USB Host Controller Drivers
#
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_UHCI_HCD=m
CONFIG_USB_OHCI_HCD=m
Also, make sure "Enforce bandwidth allocation" is NOT enabled.
# USB Multimedia devices
#
CONFIG_USB_W9968CF=m
The last module we need is "ovcamchip.o". To obtain it, you have to download
the OV511 driver, version 2.25 - don't use other versions - which is available
at http://alpha.dyndns.org/ov511/ . Then you have to download the latest
version of the full featured W996[87]CF driver, which contains a patch for the
"ovcamchip" module; it is available at http://go.lamarinapunto.com .
Once you have obtained the packages, decompress, patch and compile the
"ovcamchip" module. In other words:
[user@localhost home]$ tar xvzf w9968cf-x.x.tar.gz
[user@localhost home]$ tar xvjf ov511-2.25.tar.bz2
[user@localhost home]$ cd ov511-2.25
[user@localhost ov511-2.25]$ patch -p1 < \
/path/to/w9968cf-x.x/ov511-2.25.patch
[user@localhost ov511-2.25]$ make
It's worth to note that the full featured version of the W996[87]CF driver
can also be installed overwriting the one in the kernel; in this case, read the
documentation included in the package.
If everything went well, the W996[87]CF driver can be immediatly used (see next
paragraph).
6. Module loading
=================
To use the driver, it is necessary to load the "w9968cf" module into memory
after every other module required.
For example, loading can be done this way, as root:
[root@localhost home]# modprobe usbcore
[root@localhost home]# modprobe i2c-core
[root@localhost ov511-x.xx]# insmod ./ovcamchip.ko
[root@localhost home]# modprobe w9968cf
At this point the devices should be recognized: "dmesg" can be used to analyze
kernel messages:
[user@localhost home]$ dmesg
There are a lot of parameters the module can use to change the default
settings for each device. To list every possible parameter with a brief
explanation about them and which syntax to use, it is recommended to run the
"modinfo" command:
[root@locahost home]# modinfo w9968cf
7. Module paramaters
====================
Module paramaters are listed below:
-------------------------------------------------------------------------------
Name: vppmod_load
Type: int
Syntax: <0|1>
Description: Automatic 'w9968cf-vpp' module loading: 0 disabled, 1 enabled.
If enabled, every time an application attempts to open a
camera, 'insmod' searches for the video post-processing module
in the system and loads it automatically (if present).
The 'w9968cf-vpp' module adds extra image manipulation
capabilities to the 'w9968cf' module,like software up-scaling,
colour conversions and video decoding.
Default: 1
-------------------------------------------------------------------------------
Name: simcams
Type: int
Syntax: <n>
Description: Number of cameras allowed to stream simultaneously.
n may vary from 0 to 32.
Default: 32
-------------------------------------------------------------------------------
Name: video_nr
Type: int array (min = 0, max = 32)
Syntax: <-1|n[,...]>
Description: Specify V4L minor mode number.
-1 = use next available
n = use minor number n
You can specify 32 cameras this way.
For example:
video_nr=-1,2,-1 would assign minor number 2 to the second
recognized camera and use auto for the first one and for every
other camera.
Default: -1
-------------------------------------------------------------------------------
Name: packet_size
Type: int array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Specify the maximum data payload size in bytes for alternate
settings, for each device. n is scaled between 63 and 1023.
Default: 1023
-------------------------------------------------------------------------------
Name: max_buffers
Type: int array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Only for advanced users.
Specify the maximum number of video frame buffers to allocate
for each device, from 2 to 32.
Default: 2
-------------------------------------------------------------------------------
Name: double_buffer
Type: int array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Hardware double buffering: 0 disabled, 1 enabled.
It should be enabled if you want smooth video output: if you
obtain out of sync. video, disable it at all, or try to
decrease the 'clockdiv' module paramater value.
Default: 1 for every device.
-------------------------------------------------------------------------------
Name: clamping
Type: int array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Video data clamping: 0 disabled, 1 enabled.
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: filter_type
Type: int array (min = 0, max = 32)
Syntax: <0|1|2[,...]>
Description: Video filter type.
0 none, 1 (1-2-1) 3-tap filter, 2 (2-3-6-3-2) 5-tap filter.
The filter is used to reduce noise and aliasing artifacts
produced by the CCD or CMOS sensor.
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: largeview
Type: int array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Large view: 0 disabled, 1 enabled.
Default: 1 for every device.
-------------------------------------------------------------------------------
Name: upscaling
Type: int array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Software scaling (for non-compressed video only):
0 disabled, 1 enabled.
Disable it if you have a slow CPU or you don't have enough
memory.
Default: 0 for every device.
Note: If 'w9968cf-vpp' is not loaded, this paramater is set to 0.
-------------------------------------------------------------------------------
Name: decompression
Type: int array (min = 0, max = 32)
Syntax: <0|1|2[,...]>
Description: Software video decompression:
0 = disables decompression
(doesn't allow formats needing decompression).
1 = forces decompression
(allows formats needing decompression only).
2 = allows any permitted formats.
Formats supporting (de)compressed video are YUV422P and
YUV420P/YUV420 in any resolutions where width and height are
multiples of 16.
Default: 2 for every device.
Note: If 'w9968cf-vpp' is not loaded, forcing decompression is not
allowed; in this case this paramater is set to 2.
-------------------------------------------------------------------------------
Name: force_palette
Type: int array (min = 0, max = 32)
Syntax: <0|9|10|13|15|8|7|1|6|3|4|5[,...]>
Description: Force picture palette.
In order:
0 = Off - allows any of the following formats:
9 = UYVY 16 bpp - Original video, compression disabled
10 = YUV420 12 bpp - Original video, compression enabled
13 = YUV422P 16 bpp - Original video, compression enabled
15 = YUV420P 12 bpp - Original video, compression enabled
8 = YUVY 16 bpp - Software conversion from UYVY
7 = YUV422 16 bpp - Software conversion from UYVY
1 = GREY 8 bpp - Software conversion from UYVY
6 = RGB555 16 bpp - Software conversion from UYVY
3 = RGB565 16 bpp - Software conversion from UYVY
4 = RGB24 24 bpp - Software conversion from UYVY
5 = RGB32 32 bpp - Software conversion from UYVY
When not 0, this paramater will override 'decompression'.
Default: 0 for every device. Initial palette is 9 (UYVY).
Note: If 'w9968cf-vpp' is not loaded, this paramater is set to 9.
-------------------------------------------------------------------------------
Name: force_rgb
Type: int array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Read RGB video data instead of BGR:
1 = use RGB component ordering.
0 = use BGR component ordering.
This parameter has effect when using RGBX palettes only.
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: autobright
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: CMOS sensor automatically changes brightness:
0 = no, 1 = yes
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: autoexp
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: CMOS sensor automatically changes exposure:
0 = no, 1 = yes
Default: 1 for every device.
-------------------------------------------------------------------------------
Name: lightfreq
Type: long array (min = 0, max = 32)
Syntax: <50|60[,...]>
Description: Light frequency in Hz:
50 for European and Asian lighting, 60 for American lighting.
Default: 50 for every device.
-------------------------------------------------------------------------------
Name: bandingfilter
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Banding filter to reduce effects of fluorescent
lighting:
0 disabled, 1 enabled.
This filter tries to reduce the pattern of horizontal
light/dark bands caused by some (usually fluorescent) lighting.
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: clockdiv
Type: long array (min = 0, max = 32)
Syntax: <-1|n[,...]>
Description: Force pixel clock divisor to a specific value (for experts):
n may vary from 0 to 127.
-1 for automatic value.
See also the 'double_buffer' module paramater.
Default: -1 for every device.
-------------------------------------------------------------------------------
Name: backlight
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Objects are lit from behind:
0 = no, 1 = yes
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: mirror
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Reverse image horizontally:
0 = no, 1 = yes
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: sensor_mono
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: The CMOS sensor is monochrome:
0 = no, 1 = yes
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: brightness
Type: long array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Set picture brightness (0-65535).
This parameter has no effect if 'autobright' is enabled.
Default: 31000 for every device.
-------------------------------------------------------------------------------
Name: hue
Type: long array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Set picture hue (0-65535).
Default: 32768 for every device.
-------------------------------------------------------------------------------
Name: colour
Type: long array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Set picture saturation (0-65535).
Default: 32768 for every device.
-------------------------------------------------------------------------------
Name: contrast
Type: long array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Set picture contrast (0-65535).
Default: 50000 for every device.
-------------------------------------------------------------------------------
Name: whiteness
Type: long array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Set picture whiteness (0-65535).
Default: 32768 for every device.
-------------------------------------------------------------------------------
Name: debug
Type: int
Syntax: <n>
Description: Debugging information level, from 0 to 6:
0 = none (be cautious)
1 = critical errors
2 = significant informations
3 = configuration or general messages
4 = warnings
5 = called functions
6 = function internals
Level 5 and 6 are useful for testing only, when just one
device is used.
Default: 2
-------------------------------------------------------------------------------
Name: specific_debug
Type: int
Syntax: <0|1>
Description: Enable or disable specific debugging messages:
0 = print messages concerning every level <= 'debug' level.
1 = print messages concerning the level indicated by 'debug'.
Default: 0
-------------------------------------------------------------------------------
8. Credits
==========
The development would not have proceed much further without having looked at
the source code of other drivers and without the help of several persons; in
particular:
- the I2C interface to kernel and high-level CMOS sensor control routines have
been taken from the OV511 driver by Mark McClelland;
- memory management code has been copied from the bttv driver by Ralph Metzler,
Marcus Metzler and Gerd Knorr;
- the low-level I2C read function has been written by Frédéric Jouault, who
also gave me commented logs about sniffed USB traffic taken from another
driver for another system;
- the low-level I2C fast write function has been written by Piotr Czerczak;
This diff is collapsed.
Click to expand it.
MAINTAINERS
View file @
1a11f106
...
...
@@ -2218,6 +2218,13 @@ M: dbrownell@users.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB W996[87]CF DRIVER
P: Luca Risolia
M: luca_ing@libero.it
L: linux-usb-devel@lists.sourceforge.net
W: http://go.lamarinapunto.com
S: Maintained
USER-MODE LINUX
P: Jeff Dike
M: jdike@karaya.com
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/Makefile
View file @
1a11f106
...
...
@@ -34,6 +34,7 @@ obj-$(CONFIG_USB_PWC) += media/
obj-$(CONFIG_USB_SE401)
+=
media/
obj-$(CONFIG_USB_STV680)
+=
media/
obj-$(CONFIG_USB_VICAM)
+=
media/
obj-$(CONFIG_USB_W9968CF)
+=
media/
obj-$(CONFIG_USB_CATC)
+=
net/
obj-$(CONFIG_USB_KAWETH)
+=
net/
...
...
@@ -58,4 +59,3 @@ obj-$(CONFIG_USB_SPEEDTOUCH) += misc/
obj-$(CONFIG_USB_TEST)
+=
misc/
obj-$(CONFIG_USB_TIGL)
+=
misc/
obj-$(CONFIG_USB_USS720)
+=
misc/
This diff is collapsed.
Click to expand it.
drivers/usb/class/audio.h
View file @
1a11f106
#define USB_DT_CS_DEVICE 0x21
#define USB_DT_CS_CONFIG 0x22
#define USB_DT_CS_STRING 0x23
#define USB_DT_CS_INTERFACE 0x24
#define USB_DT_CS_ENDPOINT 0x25
#define CS_AUDIO_UNDEFINED 0x20
#define CS_AUDIO_DEVICE 0x21
#define CS_AUDIO_CONFIGURATION 0x22
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/class/cdc-acm.c
View file @
1a11f106
/*
* acm.c
Version 0.22
*
cdc-
acm.c
*
* Copyright (c) 1999 Armin Fuerst <fuerst@in.tum.de>
* Copyright (c) 1999 Pavel Machek <pavel@suse.cz>
...
...
@@ -26,6 +26,7 @@
* v0.21 - revert to probing on device for devices with multiple configs
* v0.22 - probe only the control interface. if usbcore doesn't choose the
* config we want, sysadmin changes bConfigurationValue in sysfs.
* v0.23 - use softirq for rx processing, as needed by tty layer
*/
/*
...
...
@@ -44,6 +45,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#undef DEBUG
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
...
...
@@ -54,14 +57,13 @@
#include <linux/module.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#undef DEBUG
#include <linux/usb.h>
#include <asm/byteorder.h>
/*
* Version Information
*/
#define DRIVER_VERSION "v0.2
1
"
#define DRIVER_VERSION "v0.2
3
"
#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
#define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
...
...
@@ -146,7 +148,8 @@ struct acm {
struct
tty_struct
*
tty
;
/* the corresponding tty */
struct
urb
*
ctrlurb
,
*
readurb
,
*
writeurb
;
/* urbs */
struct
acm_line
line
;
/* line coding (bits, stop, parity) */
struct
work_struct
work
;
/* work queue entry for line discipline waking up */
struct
work_struct
work
;
/* work queue entry for line discipline waking up */
struct
tasklet_struct
bh
;
/* rx processing */
unsigned
int
ctrlin
;
/* input control lines (DCD, DSR, RI, break, overruns) */
unsigned
int
ctrlout
;
/* output control lines (DTR, RTS) */
unsigned
int
writesize
;
/* max packet size for the output bulk endpoint */
...
...
@@ -184,9 +187,10 @@ static int acm_ctrl_msg(struct acm *acm, int request, int value, void *buf, int
#define acm_send_break(acm, ms) acm_ctrl_msg(acm, ACM_REQ_SEND_BREAK, ms, NULL, 0)
/*
* Interrupt handler for various ACM
control event
s
* Interrupt handler
s
for various ACM
device response
s
*/
/* control interface reports status changes with "interrupt" transfers */
static
void
acm_ctrl_irq
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
{
struct
acm
*
acm
=
urb
->
context
;
...
...
@@ -251,20 +255,30 @@ static void acm_ctrl_irq(struct urb *urb, struct pt_regs *regs)
__FUNCTION__
,
status
);
}
/* data interface returns incoming bytes, or we got unthrottled */
static
void
acm_read_bulk
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
{
struct
acm
*
acm
=
urb
->
context
;
struct
tty_struct
*
tty
=
acm
->
tty
;
unsigned
char
*
data
=
urb
->
transfer_buffer
;
int
i
=
0
;
if
(
!
ACM_READY
(
acm
))
return
;
if
(
urb
->
status
)
dbg
(
"nonzero read bulk status received: %d"
,
urb
->
status
);
dev_dbg
(
&
acm
->
data
->
dev
,
"bulk rx status %d
\n
"
,
urb
->
status
);
/* calling tty_flip_buffer_push() in_irq() isn't allowed */
tasklet_schedule
(
&
acm
->
bh
);
}
static
void
acm_rx_tasklet
(
unsigned
long
_acm
)
{
struct
acm
*
acm
=
(
void
*
)
_acm
;
struct
urb
*
urb
=
acm
->
readurb
;
struct
tty_struct
*
tty
=
acm
->
tty
;
unsigned
char
*
data
=
urb
->
transfer_buffer
;
int
i
=
0
;
if
(
!
urb
->
status
&&
!
acm
->
throttle
)
{
if
(
urb
->
actual_length
>
0
&&
!
acm
->
throttle
)
{
for
(
i
=
0
;
i
<
urb
->
actual_length
&&
!
acm
->
throttle
;
i
++
)
{
/* if we insert more than TTY_FLIPBUF_SIZE characters,
* we drop them. */
...
...
@@ -285,10 +299,12 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
urb
->
actual_length
=
0
;
urb
->
dev
=
acm
->
dev
;
if
(
usb_submit_urb
(
urb
,
GFP_ATOMIC
))
dbg
(
"failed resubmitting read urb"
);
i
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
i
)
dev_dbg
(
&
acm
->
data
->
dev
,
"bulk rx resubmit %d
\n
"
,
i
);
}
/* data interface wrote those outgoing bytes */
static
void
acm_write_bulk
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
{
struct
acm
*
acm
=
(
struct
acm
*
)
urb
->
context
;
...
...
@@ -621,6 +637,8 @@ static int acm_probe (struct usb_interface *intf,
acm
->
minor
=
minor
;
acm
->
dev
=
dev
;
acm
->
bh
.
func
=
acm_rx_tasklet
;
acm
->
bh
.
data
=
(
unsigned
long
)
acm
;
INIT_WORK
(
&
acm
->
work
,
acm_softint
,
acm
);
if
(
!
(
buf
=
kmalloc
(
ctrlsize
+
readsize
+
acm
->
writesize
,
GFP_KERNEL
)))
{
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/class/usb-midi.h
View file @
1a11f106
...
...
@@ -28,12 +28,6 @@
#define USB_SUBCLASS_MIDISTREAMING 3
#endif
#define USB_DT_CS_DEVICE 0x21
#define USB_DT_CS_CONFIG 0x22
#define USB_DT_CS_STRING 0x23
#define USB_DT_CS_INTERFACE 0x24
#define USB_DT_CS_ENDPOINT 0x25
/* ------------------------------------------------------------------------- */
/* Roland MIDI Devices */
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/class/usblp.c
View file @
1a11f106
...
...
@@ -610,7 +610,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
if
(
!
usblp
->
wcomplete
)
{
barrier
();
if
(
file
->
f_flags
&
O_NONBLOCK
)
return
-
EAGAIN
;
return
writecount
?
writecount
:
-
EAGAIN
;
timeout
=
USBLP_WRITE_TIMEOUT
;
add_wait_queue
(
&
usblp
->
wait
,
&
wait
);
...
...
@@ -673,8 +673,12 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
usblp
->
writeurb
->
dev
=
usblp
->
dev
;
usblp
->
wcomplete
=
0
;
if
(
usb_submit_urb
(
usblp
->
writeurb
,
GFP_KERNEL
))
{
count
=
-
EIO
;
err
=
usb_submit_urb
(
usblp
->
writeurb
,
GFP_KERNEL
);
if
(
err
)
{
if
(
err
!=
-
ENOMEM
)
count
=
-
EIO
;
else
count
=
writecount
?
writecount
:
-
ENOMEM
;
up
(
&
usblp
->
sem
);
break
;
}
...
...
@@ -706,8 +710,6 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count,
goto
done
;
}
// FIXME: only use urb->status inside completion
// callbacks; this way is racey...
add_wait_queue
(
&
usblp
->
wait
,
&
wait
);
while
(
1
==
1
)
{
if
(
signal_pending
(
current
))
{
...
...
@@ -1093,7 +1095,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
/* First two bytes are length in big-endian.
* They count themselves, and we copy them into
* the user's buffer. */
length
=
(
usblp
->
device_id_string
[
0
]
<<
8
)
+
usblp
->
device_id_string
[
1
]
;
length
=
be16_to_cpu
(
*
((
u16
*
)
usblp
->
device_id_string
))
;
if
(
length
<
2
)
length
=
2
;
else
if
(
length
>=
USBLP_DEVICE_ID_SIZE
)
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/core/hcd.c
View file @
1a11f106
...
...
@@ -1165,6 +1165,7 @@ static int hcd_unlink_urb (struct urb *urb)
struct
device
*
sys
=
0
;
unsigned
long
flags
;
struct
completion_splice
splice
;
struct
list_head
*
tmp
;
int
retval
;
if
(
!
urb
)
...
...
@@ -1203,7 +1204,12 @@ static int hcd_unlink_urb (struct urb *urb)
*/
WARN_ON
(
!
HCD_IS_RUNNING
(
hcd
->
state
)
&&
hcd
->
state
!=
USB_STATE_HALT
);
if
(
!
urb
->
hcpriv
)
{
/* insist the urb is still queued */
list_for_each
(
tmp
,
&
dev
->
urb_list
)
{
if
(
tmp
==
&
urb
->
urb_list
)
break
;
}
if
(
tmp
!=
&
urb
->
urb_list
)
{
retval
=
-
EINVAL
;
goto
done
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/core/hub.c
View file @
1a11f106
...
...
@@ -126,14 +126,20 @@ static int get_port_status(struct usb_device *dev, int port,
static
void
hub_irq
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
{
struct
usb_hub
*
hub
=
(
struct
usb_hub
*
)
urb
->
context
;
unsigned
long
flags
;
int
status
;
spin_lock
(
&
hub_event_lock
);
hub
->
urb_active
=
0
;
if
(
hub
->
urb_complete
)
{
/* disconnect or rmmod */
complete
(
hub
->
urb_complete
);
goto
done
;
}
switch
(
urb
->
status
)
{
case
-
ENOENT
:
/* synchronous unlink */
case
-
ECONNRESET
:
/* async unlink */
case
-
ESHUTDOWN
:
/* hardware going away */
return
;
goto
done
;
default:
/* presumably an error */
/* Cause a hub reset after 10 consecutive errors */
...
...
@@ -151,18 +157,20 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs)
hub
->
nerrors
=
0
;
/* Something happened, let khubd figure it out */
spin_lock_irqsave
(
&
hub_event_lock
,
flags
);
if
(
list_empty
(
&
hub
->
event_list
))
{
list_add
(
&
hub
->
event_list
,
&
hub_event_list
);
wake_up
(
&
khubd_wait
);
}
spin_unlock_irqrestore
(
&
hub_event_lock
,
flags
);
resubmit:
if
((
status
=
usb_submit_urb
(
hub
->
urb
,
GFP_ATOMIC
))
!=
0
/* ENODEV means we raced disconnect() */
&&
status
!=
-
ENODEV
)
dev_err
(
&
hub
->
intf
->
dev
,
"resubmit --> %d
\n
"
,
urb
->
status
);
if
(
status
==
0
)
hub
->
urb_active
=
1
;
done:
spin_unlock
(
&
hub_event_lock
);
}
/* USB 2.0 spec Section 11.24.2.3 */
...
...
@@ -467,7 +475,8 @@ static int hub_configure(struct usb_hub *hub,
message
=
"couldn't submit status urb"
;
goto
fail
;
}
hub
->
urb_active
=
1
;
/* Wake up khubd */
wake_up
(
&
khubd_wait
);
...
...
@@ -485,6 +494,7 @@ static int hub_configure(struct usb_hub *hub,
static
void
hub_disconnect
(
struct
usb_interface
*
intf
)
{
struct
usb_hub
*
hub
=
usb_get_intfdata
(
intf
);
DECLARE_COMPLETION
(
urb_complete
);
unsigned
long
flags
;
if
(
!
hub
)
...
...
@@ -492,12 +502,11 @@ static void hub_disconnect(struct usb_interface *intf)
usb_set_intfdata
(
intf
,
NULL
);
spin_lock_irqsave
(
&
hub_event_lock
,
flags
);
hub
->
urb_complete
=
&
urb_complete
;
/* Delete it and then reset it */
list_del
(
&
hub
->
event_list
);
INIT_LIST_HEAD
(
&
hub
->
event_list
);
list_del
(
&
hub
->
hub_list
);
INIT_LIST_HEAD
(
&
hub
->
hub_list
);
list_del_init
(
&
hub
->
event_list
);
list_del_init
(
&
hub
->
hub_list
);
spin_unlock_irqrestore
(
&
hub_event_lock
,
flags
);
...
...
@@ -510,6 +519,8 @@ static void hub_disconnect(struct usb_interface *intf)
if
(
hub
->
urb
)
{
usb_unlink_urb
(
hub
->
urb
);
if
(
hub
->
urb_active
)
wait_for_completion
(
&
urb_complete
);
usb_free_urb
(
hub
->
urb
);
hub
->
urb
=
NULL
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/core/hub.h
View file @
1a11f106
...
...
@@ -172,6 +172,8 @@ extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe);
struct
usb_hub
{
struct
usb_interface
*
intf
;
/* the "real" device */
struct
urb
*
urb
;
/* for interrupt polling pipe */
struct
completion
*
urb_complete
;
/* wait for urb to end */
unsigned
int
urb_active
:
1
;
/* buffer for urb ... 1 bit each for hub and children, rounded up */
char
(
*
buffer
)[(
USB_MAXCHILDREN
+
1
+
7
)
/
8
];
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/core/message.c
View file @
1a11f106
...
...
@@ -1086,6 +1086,11 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
ret
=
-
EINVAL
;
goto
out
;
}
/* The USB spec says configuration 0 means unconfigured.
* But if a device includes a configuration numbered 0,
* we will accept it as a correctly configured state.
*/
if
(
cp
&&
configuration
==
0
)
dev_warn
(
&
dev
->
dev
,
"config 0 descriptor??
\n
"
);
...
...
@@ -1101,7 +1106,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
goto
out
;
dev
->
actconfig
=
cp
;
if
(
!
c
onfiguration
)
if
(
!
c
p
)
dev
->
state
=
USB_STATE_ADDRESS
;
else
{
dev
->
state
=
USB_STATE_CONFIGURED
;
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/core/usb.c
View file @
1a11f106
...
...
@@ -80,7 +80,7 @@ static struct device_driver usb_generic_driver = {
static
int
usb_generic_driver_data
;
/*
needs to be called with BKL held
*/
/*
called from driver core with usb_bus_type.subsys writelock
*/
int
usb_probe_interface
(
struct
device
*
dev
)
{
struct
usb_interface
*
intf
=
to_usb_interface
(
dev
);
...
...
@@ -93,12 +93,14 @@ int usb_probe_interface(struct device *dev)
if
(
!
driver
->
probe
)
return
error
;
/* driver claim() doesn't yet affect dev->driver... */
if
(
intf
->
driver
)
return
error
;
id
=
usb_match_id
(
intf
,
driver
->
id_table
);
if
(
id
)
{
dev_dbg
(
dev
,
"%s - got id
\n
"
,
__FUNCTION__
);
down
(
&
driver
->
serialize
);
error
=
driver
->
probe
(
intf
,
id
);
up
(
&
driver
->
serialize
);
}
if
(
!
error
)
intf
->
driver
=
driver
;
...
...
@@ -106,23 +108,24 @@ int usb_probe_interface(struct device *dev)
return
error
;
}
/* called from driver core with usb_bus_type.subsys writelock */
int
usb_unbind_interface
(
struct
device
*
dev
)
{
struct
usb_interface
*
intf
=
to_usb_interface
(
dev
);
struct
usb_driver
*
driver
=
to_usb_driver
(
dev
->
driver
);
down
(
&
driver
->
serialize
);
struct
usb_driver
*
driver
=
intf
->
driver
;
/* release all urbs for this interface */
usb_disable_interface
(
interface_to_usbdev
(
intf
),
intf
);
if
(
intf
->
driver
&&
intf
->
driver
->
disconnect
)
intf
->
driver
->
disconnect
(
intf
);
/* force a release and re-initialize the interface */
usb_driver_release_interface
(
driver
,
intf
);
if
(
driver
&&
driver
->
disconnect
)
driver
->
disconnect
(
intf
);
up
(
&
driver
->
serialize
);
/* reset other interface state */
usb_set_interface
(
interface_to_usbdev
(
intf
),
intf
->
altsetting
[
0
].
desc
.
bInterfaceNumber
,
0
);
usb_set_intfdata
(
intf
,
NULL
);
intf
->
driver
=
NULL
;
return
0
;
}
...
...
@@ -152,8 +155,6 @@ int usb_register(struct usb_driver *new_driver)
new_driver
->
driver
.
probe
=
usb_probe_interface
;
new_driver
->
driver
.
remove
=
usb_unbind_interface
;
init_MUTEX
(
&
new_driver
->
serialize
);
retval
=
driver_register
(
&
new_driver
->
driver
);
if
(
!
retval
)
{
...
...
@@ -170,7 +171,7 @@ int usb_register(struct usb_driver *new_driver)
/**
* usb_deregister - unregister a USB driver
* @driver: USB operations of the driver to unregister
* Context:
!in_interrupt (), must be called with BKL held
* Context:
must be able to sleep
*
* Unlinks the specified driver from the internal USB driver list.
*
...
...
@@ -264,26 +265,22 @@ usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum)
* Few drivers should need to use this routine, since the most natural
* way to bind to an interface is to return the private data from
* the driver's probe() method.
*
* Callers must own the driver model's usb bus writelock. So driver
* probe() entries don't need extra locking, but other call contexts
* may need to explicitly claim that lock.
*/
int
usb_driver_claim_interface
(
struct
usb_driver
*
driver
,
struct
usb_interface
*
iface
,
void
*
priv
)
{
if
(
!
iface
||
!
driver
)
return
-
EINVAL
;
/* this is mainly to lock against usbfs */
lock_kernel
();
if
(
iface
->
driver
)
{
unlock_kernel
();
err
(
"%s driver booted %s off interface %p"
,
driver
->
name
,
iface
->
driver
->
name
,
iface
);
if
(
iface
->
driver
)
return
-
EBUSY
;
}
else
{
dbg
(
"%s driver claimed interface %p"
,
driver
->
name
,
iface
);
}
/* FIXME should device_bind_driver() */
iface
->
driver
=
driver
;
usb_set_intfdata
(
iface
,
priv
);
unlock_kernel
();
return
0
;
}
...
...
@@ -323,13 +320,22 @@ int usb_interface_claimed(struct usb_interface *iface)
* usually won't need to call this.
*
* This call is synchronous, and may not be used in an interrupt context.
* Callers must own the driver model's usb bus writelock. So driver
* disconnect() entries don't need extra locking, but other call contexts
* may need to explicitly claim that lock.
*/
void
usb_driver_release_interface
(
struct
usb_driver
*
driver
,
struct
usb_interface
*
iface
)
{
/* this should never happen, don't release something that's not ours */
if
(
iface
->
driver
&&
iface
->
driver
!=
driver
)
if
(
!
iface
||
!
iface
->
driver
||
iface
->
driver
!=
driver
)
return
;
if
(
iface
->
dev
.
driver
)
{
/* FIXME should be the ONLY case here */
device_release_driver
(
&
iface
->
dev
);
return
;
}
usb_set_interface
(
interface_to_usbdev
(
iface
),
iface
->
altsetting
[
0
].
desc
.
bInterfaceNumber
,
0
);
...
...
@@ -991,6 +997,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
int
err
=
-
EINVAL
;
int
i
;
int
j
;
int
config
;
/*
* Set the driver for the usb device to point to the "generic" driver.
...
...
@@ -1108,18 +1115,30 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
/* choose and set the configuration. that registers the interfaces
* with the driver core, and lets usb device drivers bind to them.
* NOTE: should interact with hub power budgeting.
*/
config
=
dev
->
config
[
0
].
desc
.
bConfigurationValue
;
if
(
dev
->
descriptor
.
bNumConfigurations
!=
1
)
{
for
(
i
=
0
;
i
<
dev
->
descriptor
.
bNumConfigurations
;
i
++
)
{
/* heuristic: Linux is more likely to have class
* drivers, so avoid vendor-specific interfaces.
*/
if
(
dev
->
config
[
i
].
interface
[
0
]
->
altsetting
->
desc
.
bInterfaceClass
==
USB_CLASS_VENDOR_SPEC
)
continue
;
config
=
dev
->
config
[
i
].
desc
.
bConfigurationValue
;
break
;
}
dev_info
(
&
dev
->
dev
,
"configuration #%d chosen from %d choices
\n
"
,
dev
->
config
[
0
].
desc
.
bConfigurationValue
,
config
,
dev
->
descriptor
.
bNumConfigurations
);
}
err
=
usb_set_configuration
(
dev
,
dev
->
config
[
0
].
desc
.
bConfigurationValue
);
err
=
usb_set_configuration
(
dev
,
config
);
if
(
err
)
{
dev_err
(
&
dev
->
dev
,
"can't set config #%d, error %d
\n
"
,
dev
->
config
[
0
].
desc
.
bConfigurationValue
,
err
);
config
,
err
);
device_del
(
&
dev
->
dev
);
goto
fail
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/host/ohci-dbg.c
View file @
1a11f106
...
...
@@ -269,18 +269,19 @@ static void ohci_dump (struct ohci_hcd *controller, int verbose)
ohci_dump_status
(
controller
,
NULL
,
0
);
if
(
controller
->
hcca
)
ohci_dbg
(
controller
,
"hcca frame #%04x
\n
"
,
controller
->
hcca
->
frame_no
);
"hcca frame #%04x
\n
"
,
OHCI_FRAME_NO
(
controller
->
hcca
)
);
ohci_dump_roothub
(
controller
,
1
,
NULL
,
0
);
}
static
const
char
data0
[]
=
"DATA0"
;
static
const
char
data1
[]
=
"DATA1"
;
static
void
ohci_dump_td
(
struct
ohci_hcd
*
ohci
,
char
*
label
,
struct
td
*
td
)
static
void
ohci_dump_td
(
const
struct
ohci_hcd
*
ohci
,
const
char
*
label
,
const
struct
td
*
td
)
{
u32
tmp
=
le32_to_cpup
(
&
td
->
hwINFO
);
ohci_dbg
(
ohci
,
"%s td %p%s; urb %p index %d; hw next td %08x"
,
ohci_dbg
(
ohci
,
"%s td %p%s; urb %p index %d; hw next td %08x
\n
"
,
label
,
td
,
(
tmp
&
TD_DONE
)
?
" (DONE)"
:
""
,
td
->
urb
,
td
->
index
,
...
...
@@ -301,28 +302,28 @@ static void ohci_dump_td (struct ohci_hcd *ohci, char *label, struct td *td)
case
TD_DP_OUT
:
pid
=
"OUT"
;
break
;
default:
pid
=
"(bad pid)"
;
break
;
}
ohci_dbg
(
ohci
,
" info %08x CC=%x %s DI=%d %s %s"
,
tmp
,
ohci_dbg
(
ohci
,
" info %08x CC=%x %s DI=%d %s %s
\n
"
,
tmp
,
TD_CC_GET
(
tmp
),
/* EC, */
toggle
,
(
tmp
&
TD_DI
)
>>
21
,
pid
,
(
tmp
&
TD_R
)
?
"R"
:
""
);
cbp
=
le32_to_cpup
(
&
td
->
hwCBP
);
be
=
le32_to_cpup
(
&
td
->
hwBE
);
ohci_dbg
(
ohci
,
" cbp %08x be %08x (len %d)"
,
cbp
,
be
,
ohci_dbg
(
ohci
,
" cbp %08x be %08x (len %d)
\n
"
,
cbp
,
be
,
cbp
?
(
be
+
1
-
cbp
)
:
0
);
}
else
{
unsigned
i
;
ohci_dbg
(
ohci
,
"
info %08x CC=%x FC=%d DI=%d SF=%04x"
,
tmp
,
ohci_dbg
(
ohci
,
" info %08x CC=%x FC=%d DI=%d SF=%04x
\n
"
,
tmp
,
TD_CC_GET
(
tmp
),
(
tmp
>>
24
)
&
0x07
,
(
tmp
&
TD_DI
)
>>
21
,
tmp
&
0x0000ffff
);
ohci_dbg
(
ohci
,
"
bp0 %08x be %08x"
,
ohci_dbg
(
ohci
,
" bp0 %08x be %08x
\n
"
,
le32_to_cpup
(
&
td
->
hwCBP
)
&
~
0x0fff
,
le32_to_cpup
(
&
td
->
hwBE
));
for
(
i
=
0
;
i
<
MAXPSW
;
i
++
)
{
u16
psw
=
le16_to_cpup
(
&
td
->
hwPSW
[
i
]);
int
cc
=
(
psw
>>
12
)
&
0x0f
;
ohci_dbg
(
ohci
,
"
psw [%d] = %2x, CC=%x %s=%d"
,
i
,
ohci_dbg
(
ohci
,
" psw [%d] = %2x, CC=%x %s=%d
\n
"
,
i
,
psw
,
cc
,
(
cc
>=
0x0e
)
?
"OFFSET"
:
"SIZE"
,
psw
&
0x0fff
);
...
...
@@ -332,12 +333,13 @@ static void ohci_dump_td (struct ohci_hcd *ohci, char *label, struct td *td)
/* caller MUST own hcd spinlock if verbose is set! */
static
void
__attribute__
((
unused
))
ohci_dump_ed
(
struct
ohci_hcd
*
ohci
,
char
*
label
,
struct
ed
*
ed
,
int
verbose
)
ohci_dump_ed
(
const
struct
ohci_hcd
*
ohci
,
const
char
*
label
,
const
struct
ed
*
ed
,
int
verbose
)
{
u32
tmp
=
ed
->
hwINFO
;
char
*
type
=
""
;
ohci_dbg
(
ohci
,
"%s, ed %p state 0x%x type %s; next ed %08x"
,
ohci_dbg
(
ohci
,
"%s, ed %p state 0x%x type %s; next ed %08x
\n
"
,
label
,
ed
,
ed
->
state
,
edstring
(
ed
->
type
),
le32_to_cpup
(
&
ed
->
hwNextED
));
...
...
@@ -347,7 +349,7 @@ ohci_dump_ed (struct ohci_hcd *ohci, char *label, struct ed *ed, int verbose)
/* else from TDs ... control */
}
ohci_dbg
(
ohci
,
" info %08x MAX=%d%s%s%s%s EP=%d%s DEV=%d"
,
le32_to_cpu
(
tmp
),
" info %08x MAX=%d%s%s%s%s EP=%d%s DEV=%d
\n
"
,
le32_to_cpu
(
tmp
),
0x03ff
&
(
le32_to_cpu
(
tmp
)
>>
16
),
(
tmp
&
ED_DEQUEUE
)
?
" DQ"
:
""
,
(
tmp
&
ED_ISO
)
?
" ISO"
:
""
,
...
...
@@ -356,7 +358,7 @@ ohci_dump_ed (struct ohci_hcd *ohci, char *label, struct ed *ed, int verbose)
0x000f
&
(
le32_to_cpu
(
tmp
)
>>
7
),
type
,
0x007f
&
le32_to_cpu
(
tmp
));
ohci_dbg
(
ohci
,
" tds: head %08x %s%s tail %08x%s"
,
ohci_dbg
(
ohci
,
" tds: head %08x %s%s tail %08x%s
\n
"
,
tmp
=
le32_to_cpup
(
&
ed
->
hwHeadP
),
(
ed
->
hwHeadP
&
ED_C
)
?
data1
:
data0
,
(
ed
->
hwHeadP
&
ED_H
)
?
" HALT"
:
""
,
...
...
@@ -541,24 +543,29 @@ show_periodic (struct class_device *class_dev, char *buf)
if
(
temp
==
seen_count
)
{
u32
info
=
ed
->
hwINFO
;
u32
scratch
=
cpu_to_le32p
(
&
ed
->
hwINFO
);
struct
list_head
*
entry
;
unsigned
qlen
=
0
;
/* qlen measured here in TDs, not urbs */
list_for_each
(
entry
,
&
ed
->
td_list
)
qlen
++
;
temp
=
snprintf
(
next
,
size
,
" (%cs dev%d
%s
ep%d%s"
" (%cs dev%d ep%d%s
-%s qlen %u
"
" max %d %08x%s%s)"
,
(
info
&
ED_LOWSPEED
)
?
'l'
:
'f'
,
scratch
&
0x7f
,
(
info
&
ED_ISO
)
?
" iso"
:
""
,
(
scratch
>>
7
)
&
0xf
,
(
info
&
ED_IN
)
?
"in"
:
"out"
,
(
info
&
ED_ISO
)
?
"iso"
:
"int"
,
qlen
,
0x03ff
&
(
scratch
>>
16
),
scratch
,
(
info
&
ED_SKIP
)
?
"
s
"
:
""
,
(
info
&
ED_SKIP
)
?
"
K
"
:
""
,
(
ed
->
hwHeadP
&
ED_H
)
?
" H"
:
""
);
size
-=
temp
;
next
+=
temp
;
// FIXME some TD info too
if
(
seen_count
<
DBG_SCHED_LIMIT
)
seen
[
seen_count
++
]
=
ed
;
...
...
@@ -617,7 +624,7 @@ show_registers (struct class_device *class_dev, char *buf)
/* hcca */
if
(
ohci
->
hcca
)
ohci_dbg_sw
(
ohci
,
&
next
,
&
size
,
"hcca frame 0x%04x
\n
"
,
ohci
->
hcca
->
frame_no
);
"hcca frame 0x%04x
\n
"
,
OHCI_FRAME_NO
(
ohci
->
hcca
)
);
/* other registers mostly affect frame timings */
rdata
=
readl
(
&
regs
->
fminterval
);
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/host/ohci-hcd.c
View file @
1a11f106
...
...
@@ -226,7 +226,7 @@ static int ohci_urb_enqueue (
if
(
retval
<
0
)
goto
fail
;
if
(
ed
->
type
==
PIPE_ISOCHRONOUS
)
{
u16
frame
=
le16_to_cpu
(
ohci
->
hcca
->
frame_no
);
u16
frame
=
OHCI_FRAME_NO
(
ohci
->
hcca
);
/* delay a few frames before the first TD */
frame
+=
max_t
(
u16
,
8
,
ed
->
interval
);
...
...
@@ -281,7 +281,7 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
urb_priv
=
urb
->
hcpriv
;
if
(
urb_priv
)
{
if
(
urb_priv
->
ed
->
state
==
ED_OPER
)
start_
urb
_unlink
(
ohci
,
urb_priv
->
ed
);
start_
ed
_unlink
(
ohci
,
urb_priv
->
ed
);
}
}
else
{
/*
...
...
@@ -363,7 +363,7 @@ static int ohci_get_frame (struct usb_hcd *hcd)
{
struct
ohci_hcd
*
ohci
=
hcd_to_ohci
(
hcd
);
return
le16_to_cpu
(
ohci
->
hcca
->
frame_no
);
return
OHCI_FRAME_NO
(
ohci
->
hcca
);
}
/*-------------------------------------------------------------------------*
...
...
@@ -591,7 +591,7 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
*/
spin_lock
(
&
ohci
->
lock
);
if
(
ohci
->
ed_rm_list
)
finish_unlinks
(
ohci
,
le16_to_cpu
(
ohci
->
hcca
->
frame_no
),
finish_unlinks
(
ohci
,
OHCI_FRAME_NO
(
ohci
->
hcca
),
ptregs
);
if
((
ints
&
OHCI_INTR_SF
)
!=
0
&&
!
ohci
->
ed_rm_list
&&
HCD_IS_RUNNING
(
ohci
->
hcd
.
state
))
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/host/ohci-q.c
View file @
1a11f106
...
...
@@ -430,7 +430,7 @@ static struct ed *ed_get (
* put the ep on the rm_list
* real work is done at the next start frame (SF) hardware interrupt
*/
static
void
start_
urb
_unlink
(
struct
ohci_hcd
*
ohci
,
struct
ed
*
ed
)
static
void
start_
ed
_unlink
(
struct
ohci_hcd
*
ohci
,
struct
ed
*
ed
)
{
ed
->
hwINFO
|=
ED_DEQUEUE
;
ed
->
state
=
ED_UNLINK
;
...
...
@@ -441,7 +441,7 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed)
* behave. frame_no wraps every 2^16 msec, and changes right before
* SF is triggered.
*/
ed
->
tick
=
le16_to_cpu
(
ohci
->
hcca
->
frame_no
)
+
1
;
ed
->
tick
=
OHCI_FRAME_NO
(
ohci
->
hcca
)
+
1
;
/* rm_list is just singly linked, for simplicity */
ed
->
ed_next
=
ohci
->
ed_rm_list
;
...
...
@@ -479,7 +479,8 @@ td_fill (struct ohci_hcd *ohci, u32 info,
* and iso; other urbs rarely need more than one TD per urb.
* this way, only final tds (or ones with an error) cause IRQs.
* at least immediately; use DI=6 in case any control request is
* tempted to die part way through.
* tempted to die part way through. (and to force the hc to flush
* its donelist soonish, even on unlink paths.)
*
* NOTE: could delay interrupts even for the last TD, and get fewer
* interrupts ... increasing per-urb latency by sharing interrupts.
...
...
@@ -879,12 +880,27 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
u32
*
prev
;
/* only take off EDs that the HC isn't using, accounting for
* frame counter wraps
.
* frame counter wraps
and EDs with partially retired TDs
*/
if
(
tick_before
(
tick
,
ed
->
tick
)
&&
HCD_IS_RUNNING
(
ohci
->
hcd
.
state
))
{
last
=
&
ed
->
ed_next
;
continue
;
if
(
likely
(
HCD_IS_RUNNING
(
ohci
->
hcd
.
state
)))
{
if
(
tick_before
(
tick
,
ed
->
tick
))
{
skip_ed:
last
=
&
ed
->
ed_next
;
continue
;
}
if
(
!
list_empty
(
&
ed
->
td_list
))
{
struct
td
*
td
;
u32
head
;
td
=
list_entry
(
ed
->
td_list
.
next
,
struct
td
,
td_list
);
head
=
cpu_to_le32
(
ed
->
hwHeadP
)
&
TD_MASK
;
/* INTR_WDH may need to clean up first */
if
(
td
->
td_dma
!=
head
)
goto
skip_ed
;
}
}
/* reentrancy: if we drop the schedule lock, someone might
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/host/ohci.h
View file @
1a11f106
...
...
@@ -172,8 +172,14 @@ static const int cc_to_error [16] = {
struct
ohci_hcca
{
#define NUM_INTS 32
__u32
int_table
[
NUM_INTS
];
/* periodic schedule */
__u16
frame_no
;
/* current frame number */
__u16
pad1
;
/* set to 0 on each frame_no change */
/*
* OHCI defines u16 frame_no, followed by u16 zero pad.
* Since some processors can't do 16 bit bus accesses,
* portable access must be a 32 bit byteswapped access.
*/
u32
frame_no
;
/* current frame number */
#define OHCI_FRAME_NO(hccap) ((u16)le32_to_cpup(&(hccap)->frame_no))
__u32
done_head
;
/* info returned for an interrupt */
u8
reserved_for_hc
[
116
];
u8
what
[
4
];
/* spec only identifies 252 bytes :) */
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/image/scanner.c
View file @
1a11f106
...
...
@@ -380,6 +380,10 @@
* Visioneer scanners.
* - Added test for USB_CLASS_CDC_DATA which is used by some fingerprint scanners.
*
* 0.4.16 2003-11-04
* - Added vendor/product ids for Epson, Genius, Microtek, Plustek, Reflecta, and
* Visioneer scanners. Removed ids for HP PSC devices as these are supported by
* the hpoj userspace driver.
*
* TODO
* - Performance
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/image/scanner.h
View file @
1a11f106
...
...
@@ -43,7 +43,7 @@
// #define DEBUG
#define DRIVER_VERSION "0.4.1
5
"
#define DRIVER_VERSION "0.4.1
6
"
#define DRIVER_DESC "USB Scanner Driver"
#include <linux/usb.h>
...
...
@@ -146,7 +146,12 @@ static struct usb_device_id scanner_device_ids [] = {
{
USB_DEVICE
(
0x0458
,
0x2015
)
},
/* ColorPage HR7LE */
{
USB_DEVICE
(
0x0458
,
0x2016
)
},
/* ColorPage HR6X */
{
USB_DEVICE
(
0x0458
,
0x2018
)
},
/* ColorPage HR7X */
{
USB_DEVICE
(
0x0458
,
0x201b
)
},
/* Colorpage Vivid 4x */
/* Hewlett Packard */
/* IMPORTANT: Hewlett-Packard multi-function peripherals (OfficeJet,
Printer/Scanner/Copier (PSC), LaserJet, or PhotoSmart printer)
should not be added to this table because they are accessed by a
userspace driver (hpoj) */
{
USB_DEVICE
(
0x03f0
,
0x0101
)
},
/* ScanJet 4100C */
{
USB_DEVICE
(
0x03f0
,
0x0102
)
},
/* PhotoSmart S20 */
{
USB_DEVICE
(
0x03f0
,
0x0105
)
},
/* ScanJet 4200C */
...
...
@@ -168,10 +173,10 @@ static struct usb_device_id scanner_device_ids [] = {
{
USB_DEVICE
(
0x03F0
,
0x1105
)
},
/* ScanJet 5470C */
{
USB_DEVICE
(
0x03f0
,
0x1205
)
},
/* ScanJet 5550C */
{
USB_DEVICE
(
0x03f0
,
0x1305
)
},
/* Scanjet 4570c */
{
USB_DEVICE
(
0x03f0
,
0x1411
)
},
/* PSC 750 */
//
{ USB_DEVICE(0x03f0, 0x1411) }, /* PSC 750
- NOT SUPPORTED - use hpoj userspace driver
*/
{
USB_DEVICE
(
0x03f0
,
0x2005
)
},
/* ScanJet 3570c */
{
USB_DEVICE
(
0x03f0
,
0x2205
)
},
/* ScanJet 3500c */
{
USB_DEVICE
(
0x03f0
,
0x2f11
)
},
/* PSC 1210 */
//
{ USB_DEVICE(0x03f0, 0x2f11) }, /* PSC 1210
- NOT SUPPORTED - use hpoj userspace driver
*/
/* Lexmark */
{
USB_DEVICE
(
0x043d
,
0x002d
)
},
/* X70/X73 */
{
USB_DEVICE
(
0x043d
,
0x003d
)
},
/* X83 */
...
...
@@ -187,6 +192,7 @@ static struct usb_device_id scanner_device_ids [] = {
{
USB_DEVICE
(
0x05da
,
0x30ce
)
},
/* ScanMaker 3800 */
{
USB_DEVICE
(
0x05da
,
0x30cf
)
},
/* ScanMaker 4800 */
{
USB_DEVICE
(
0x05da
,
0x30d4
)
},
/* ScanMaker 3830 + 3840 */
{
USB_DEVICE
(
0x05da
,
0x30d8
)
},
/* ScanMaker 5900 */
{
USB_DEVICE
(
0x04a7
,
0x0224
)
},
/* Scanport 3000 (actually Visioneer?)*/
/* The following SCSI-over-USB Microtek devices are supported by the
microtek driver: Enable SCSI and USB Microtek in kernel config */
...
...
@@ -245,6 +251,7 @@ static struct usb_device_id scanner_device_ids [] = {
{
USB_DEVICE
(
0x07b3
,
0x0400
)
},
/* OpticPro 1248U */
{
USB_DEVICE
(
0x07b3
,
0x0401
)
},
/* OpticPro 1248U (another one) */
{
USB_DEVICE
(
0x07b3
,
0x0403
)
},
/* U16B */
{
USB_DEVICE
(
0x07b3
,
0x0413
)
},
/* OpticSlim 1200 */
/* Primax/Colorado */
{
USB_DEVICE
(
0x0461
,
0x0300
)
},
/* G2-300 #1 */
{
USB_DEVICE
(
0x0461
,
0x0301
)
},
/* G2E-300 #1 */
...
...
@@ -261,6 +268,8 @@ static struct usb_device_id scanner_device_ids [] = {
{
USB_DEVICE
(
0x0461
,
0x0383
)
},
/* G2E-600 */
/* Prolink */
{
USB_DEVICE
(
0x06dc
,
0x0014
)
},
/* Winscan Pro 2448U */
/* Reflecta */
{
USB_DEVICE
(
0x05e3
,
0x0120
)
},
/* iScan 1800 */
/* Relisis */
// { USB_DEVICE(0x0475, 0x0103) }, /* Episode - undetected endpoint */
{
USB_DEVICE
(
0x0475
,
0x0210
)
},
/* Scorpio Ultra 3 */
...
...
@@ -285,6 +294,7 @@ static struct usb_device_id scanner_device_ids [] = {
{
USB_DEVICE
(
0x04b8
,
0x011c
)
},
/* Perfection 3200 */
{
USB_DEVICE
(
0x04b8
,
0x011d
)
},
/* Perfection 1260 */
{
USB_DEVICE
(
0x04b8
,
0x011e
)
},
/* Perfection 1660 Photo */
{
USB_DEVICE
(
0x04b8
,
0x011f
)
},
/* Perfection 1670 */
{
USB_DEVICE
(
0x04b8
,
0x0801
)
},
/* Stylus CX5200 */
{
USB_DEVICE
(
0x04b8
,
0x0802
)
},
/* Stylus CX3200 */
/* Siemens */
...
...
@@ -309,6 +319,7 @@ static struct usb_device_id scanner_device_ids [] = {
{
USB_DEVICE
(
0x04a7
,
0x0221
)
},
/* OneTouch 5300 USB */
{
USB_DEVICE
(
0x04a7
,
0x0224
)
},
/* OneTouch 4800 USB */
{
USB_DEVICE
(
0x04a7
,
0x0226
)
},
/* OneTouch 5800 USB */
{
USB_DEVICE
(
0x04a7
,
0x0229
)
},
/* OneTouch 7100 USB */
{
USB_DEVICE
(
0x04a7
,
0x022c
)
},
/* OneTouch 9020 USB */
{
USB_DEVICE
(
0x04a7
,
0x0231
)
},
/* 6100 USB */
{
USB_DEVICE
(
0x04a7
,
0x0311
)
},
/* 6200 EPP/USB */
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/media/Kconfig
View file @
1a11f106
...
...
@@ -113,16 +113,17 @@ config USB_PWC
webcams:
* Philips PCA645, PCA646
* Philips PCVC675, PCVC680, PCVC690
* Philips PCVC730, PCVC740, PCVC750
* Philips
PCVC720/40,
PCVC730, PCVC740, PCVC750
* Askey VC010
* Logitech QuickCam Pro 3000, 4000, 'Zoom' and 'Notebook'
* Samsung MPC-C10, MPC-C30
* Creative Webcam 5
* SOTECT Afina Eye
* Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro'
and 'Orbit'/'Sphere'
* Samsung MPC-C10, MPC-C30
* Creative Webcam 5, Pro Ex
* SOTEC Afina Eye
* Visionite VCS-UC300, VCS-UM100
The PCA635, PCVC665 and PCVC720 are not supported by this driver
and never will be, but the 665 and 720 are supported by other
The PCA635, PCVC665 and PCVC720
/20
are not supported by this driver
and never will be, but the 665 and 720
/20
are supported by other
drivers.
This driver has an optional plugin (called PWCX), which is
...
...
@@ -177,3 +178,30 @@ config USB_STV680
To compile this driver as a module, choose M here: the
module will be called stv680.
config USB_W9968CF
tristate "USB W996[87]CF JPEG Dual Mode Camera support"
depends on USB && VIDEO_DEV && I2C
---help---
Say Y here if you want support for cameras based on
Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
This driver has an optional plugin, which is distributed as a
separate module only (released under GPL). It contains code that
allows you to use higher resolutions and framerates, and can't
be included into the official Linux kernel for performance
purposes.
At the moment the driver needs a third-part module for the CMOS
sensors, which is available on internet: it is recommended to read
<file:Documentation/usb/w9968cf.txt> for more informations and for
a list of supported cameras.
This driver uses the Video For Linux and the I2C APIs.
You must say Y or M to both "Video For Linux" and
"I2C Support" to use this driver.
Information on this API and pointers to "v4l" programs may be found
on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called w9968cf.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
This diff is collapsed.
Click to expand it.
Prev
1
2
3
4
Next
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