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
f0dbe47d
Commit
f0dbe47d
authored
Apr 28, 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
2ce059ec
f123a327
Changes
25
Show whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
793 additions
and
440 deletions
+793
-440
Documentation/usb/ehci.txt
Documentation/usb/ehci.txt
+11
-4
drivers/usb/Config.help
drivers/usb/Config.help
+8
-0
drivers/usb/class/printer.c
drivers/usb/class/printer.c
+15
-6
drivers/usb/core/Config.in
drivers/usb/core/Config.in
+4
-7
drivers/usb/core/usb.c
drivers/usb/core/usb.c
+155
-20
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-hub.c
+20
-16
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-hub.c
+4
-1
drivers/usb/image/mdc800.c
drivers/usb/image/mdc800.c
+9
-0
drivers/usb/image/scanner.c
drivers/usb/image/scanner.c
+6
-3
drivers/usb/image/scanner.h
drivers/usb/image/scanner.h
+5
-0
drivers/usb/input/hid-core.c
drivers/usb/input/hid-core.c
+2
-0
drivers/usb/input/hiddev.c
drivers/usb/input/hiddev.c
+20
-8
drivers/usb/media/Makefile
drivers/usb/media/Makefile
+1
-1
drivers/usb/media/dabusb.c
drivers/usb/media/dabusb.c
+12
-3
drivers/usb/media/dabusb.h
drivers/usb/media/dabusb.h
+5
-0
drivers/usb/media/usbvideo.c
drivers/usb/media/usbvideo.c
+72
-28
drivers/usb/media/usbvideo.h
drivers/usb/media/usbvideo.h
+1
-28
drivers/usb/misc/auerswald.c
drivers/usb/misc/auerswald.c
+23
-11
drivers/usb/misc/brlvger.c
drivers/usb/misc/brlvger.c
+12
-9
drivers/usb/net/pegasus.h
drivers/usb/net/pegasus.h
+2
-0
drivers/usb/net/usbnet.c
drivers/usb/net/usbnet.c
+11
-22
drivers/usb/serial/keyspan.c
drivers/usb/serial/keyspan.c
+130
-41
drivers/usb/usb-skeleton.c
drivers/usb/usb-skeleton.c
+24
-14
include/linux/brlvger.h
include/linux/brlvger.h
+6
-1
include/linux/usb.h
include/linux/usb.h
+235
-217
No files found.
Documentation/usb/ehci.txt
View file @
f0dbe47d
18-Dec-2001
26-Apr-2002
The EHCI driver is used to talk to high speed USB 2.0 devices using
USB 2.0-capable host controller hardware. The USB 2.0 standard is
...
...
@@ -19,6 +19,9 @@ interact with the EHCI controller through a "Transaction Translator"
(TT) in the hub, which turns low or full speed transactions into
high speed "split transactions" that don't waste transfer bandwidth.
At this writing, this driver has been seen to work with implementations
of EHCI from (in alphabetical order): Intel, NEC, Philips, and VIA.
At this writing, high speed devices are finally beginning to appear.
While usb-storage devices have been available for some time (working
quite speedily on the 2.4 version of this driver), hubs have only
...
...
@@ -36,7 +39,7 @@ APIs exposed to USB device drivers.
FUNCTIONALITY
This driver is regularly tested on x86 hardware, and has also been
used on PPC hardware so big/little endianne
e
ss issues should be gone.
used on PPC hardware so big/little endianness issues should be gone.
It's believed to do all the right PCI magic so that I/O works even on
systems with interesting DMA mapping issues.
...
...
@@ -51,11 +54,13 @@ scheduling for interrupt transfers, which means among other things that
connecting USB 1.1 hubs, keyboards, and mice to USB 2.0 hubs won't work.
Connect them to USB 1.1 hubs, or to a root hub.
Isochronous (ISO) transfer support is
not yet working
. No production
Isochronous (ISO) transfer support is
also newly functional
. No production
high speed devices are available which would need it (though high quality
webcams are in the works!). Note that split transaction support for ISO
transfers can't share much code with the code for high speed ISO transfers,
since EHCI represents these with a different data structure.
since EHCI represents these with a different data structure. So for now,
most USB audio and video devices have the same restrictions as hubs, mice,
and keyboards: don't connect them using high speed USB hubs.
The EHCI root hub code should hand off USB 1.1 devices to its companion
controller. This driver doesn't need to know anything about those
...
...
@@ -99,6 +104,8 @@ Device drivers shouldn't care whether they're running over EHCI or not,
but they may want to check for "usb_device->speed == USB_SPEED_HIGH".
High speed devices can do things that full speed (or low speed) ones
can't, such as "high bandwidth" periodic (interrupt or ISO) transfers.
Also, some values in device descriptors (such as polling intervals for
periodic transfers) use different encodings when operating at high speed.
PERFORMANCE
...
...
drivers/usb/Config.help
View file @
f0dbe47d
...
...
@@ -69,3 +69,11 @@ CONFIG_USB_BANDWIDTH
If you say N here, these conditions will cause warning messages
about USB bandwidth usage to be logged and some devices or
drivers may not work correctly.
CONFIG_USB_DYNAMIC_MINORS
If you say Y here, the USB subsystem will use dynamic minor
allocation for any device that uses the USB major number.
This means that you can have more than 16 of a single type
of device (like USB printers).
If you are unsure about this, say N here.
drivers/usb/class/printer.c
View file @
f0dbe47d
...
...
@@ -107,7 +107,11 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H
#define USBLP_REQ_RESET 0x02
#define USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST 0x00
/* HP Vendor-specific */
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define USBLP_MINORS 256
#else
#define USBLP_MINORS 16
#endif
#define USBLP_MINOR_BASE 0
#define USBLP_WRITE_TIMEOUT (5*HZ)
/* 5 seconds */
...
...
@@ -208,6 +212,8 @@ static int usblp_select_alts(struct usblp *usblp);
static
int
usblp_set_protocol
(
struct
usblp
*
usblp
,
int
protocol
);
static
int
usblp_cache_device_id_string
(
struct
usblp
*
usblp
);
/* forward reference to make our lives easier */
extern
struct
usb_driver
usblp_driver
;
/*
* Functions for usblp control messages.
...
...
@@ -366,6 +372,7 @@ static void usblp_cleanup (struct usblp *usblp)
{
devfs_unregister
(
usblp
->
devfs
);
usblp_table
[
usblp
->
minor
]
=
NULL
;
usb_deregister_dev
(
&
usblp_driver
,
1
,
usblp
->
minor
);
info
(
"usblp%d: removed"
,
usblp
->
minor
);
kfree
(
usblp
->
writeurb
->
transfer_buffer
);
...
...
@@ -801,7 +808,8 @@ static void *usblp_probe(struct usb_device *dev, unsigned int ifnum,
init_waitqueue_head
(
&
usblp
->
wait
);
usblp
->
ifnum
=
ifnum
;
/* Look for a free usblp_table entry. */
if
(
usb_register_dev
(
&
usblp_driver
,
1
,
&
usblp
->
minor
))
{
/* Look for a free usblp_table entry on our own. */
while
(
usblp_table
[
usblp
->
minor
])
{
usblp
->
minor
++
;
if
(
usblp
->
minor
>=
USBLP_MINORS
)
{
...
...
@@ -809,6 +817,7 @@ static void *usblp_probe(struct usb_device *dev, unsigned int ifnum,
goto
abort
;
}
}
}
usblp
->
writeurb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
usblp
->
writeurb
)
{
...
...
drivers/usb/core/Config.in
View file @
f0dbe47d
...
...
@@ -4,11 +4,8 @@
bool ' USB verbose debug messages' CONFIG_USB_DEBUG
comment 'Miscellaneous USB options'
bool ' USB device filesystem' CONFIG_USB_DEVICEFS
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' Enforce USB bandwidth allocation (EXPERIMENTAL)' CONFIG_USB_BANDWIDTH
else
define_bool CONFIG_USB_BANDWIDTH n
fi
bool ' Long timeout for slow-responding devices (some MGE Ellipse UPSes)' CONFIG_USB_LONG_TIMEOUT
bool ' USB device filesystem' CONFIG_USB_DEVICEFS
bool ' Long timeout for slow-responding devices (some MGE Ellipse UPSes)' CONFIG_USB_LONG_TIMEOUT
dep_bool ' Enforce USB bandwidth allocation (EXPERIMENTAL)' CONFIG_USB_BANDWIDTH $CONFIG_EXPERIMENTAL
dep_bool ' Dynamic USB minor allocation (EXPERIMENTAL)' CONFIG_USB_DYNAMIC_MINORS $CONFIG_EXPERIMENTAL
drivers/usb/core/usb.c
View file @
f0dbe47d
...
...
@@ -11,6 +11,7 @@
more docs, etc)
* (C) Copyright Yggdrasil Computing, Inc. 2000
* (usb_device_id matching changes by Adam J. Richter)
* (C) Copyright Greg Kroah-Hartman 2002
*
* NOTE! This is not actually a driver at all, rather this is
* just a collection of helper routines that implement the
...
...
@@ -59,7 +60,47 @@ LIST_HEAD(usb_driver_list);
devfs_handle_t
usb_devfs_handle
;
/* /dev/usb dir. */
static
struct
usb_driver
*
usb_minors
[
256
];
#define MAX_USB_MINORS 256
static
struct
usb_driver
*
usb_minors
[
MAX_USB_MINORS
];
static
spinlock_t
minor_lock
=
SPIN_LOCK_UNLOCKED
;
static
int
usb_register_minors
(
struct
usb_driver
*
driver
,
int
num_minors
,
int
start_minor
)
{
int
i
;
dbg
(
"registering %d minors, starting at %d"
,
num_minors
,
start_minor
);
if
(
start_minor
+
num_minors
>=
MAX_USB_MINORS
)
return
-
EINVAL
;
spin_lock
(
&
minor_lock
);
for
(
i
=
start_minor
;
i
<
(
start_minor
+
num_minors
);
++
i
)
if
(
usb_minors
[
i
])
{
spin_unlock
(
&
minor_lock
);
err
(
"minor %d is already in use, error registering %s driver"
,
i
,
driver
->
name
);
return
-
EINVAL
;
}
for
(
i
=
start_minor
;
i
<
(
start_minor
+
num_minors
);
++
i
)
usb_minors
[
i
]
=
driver
;
spin_unlock
(
&
minor_lock
);
return
0
;
}
static
void
usb_deregister_minors
(
struct
usb_driver
*
driver
,
int
num_minors
,
int
start_minor
)
{
int
i
;
dbg
(
"%s is removing %d minors starting at %d"
,
driver
->
name
,
num_minors
,
start_minor
);
spin_lock
(
&
minor_lock
);
for
(
i
=
start_minor
;
i
<
(
start_minor
+
num_minors
);
++
i
)
usb_minors
[
i
]
=
NULL
;
spin_unlock
(
&
minor_lock
);
}
/**
* usb_register - register a USB driver
...
...
@@ -72,18 +113,20 @@ static struct usb_driver *usb_minors[256];
*/
int
usb_register
(
struct
usb_driver
*
new_driver
)
{
int
i
;
int
retval
=
0
;
if
(
new_driver
->
fops
!=
NULL
)
{
for
(
i
=
new_driver
->
minor
;
i
<
new_driver
->
minor
+
new_driver
->
num_minors
;
++
i
)
{
if
(
usb_minors
[
i
])
{
err
(
"error registering %s driver"
,
new_driver
->
name
);
if
((
new_driver
->
fops
)
&&
(
new_driver
->
num_minors
==
0
))
{
err
(
"%s driver must specify num_minors"
,
new_driver
->
name
);
return
-
EINVAL
;
}
#ifndef CONFIG_USB_DYNAMIC_MINORS
if
(
new_driver
->
fops
!=
NULL
)
{
retval
=
usb_register_minors
(
new_driver
,
new_driver
->
num_minors
,
new_driver
->
minor
);
if
(
retval
)
return
retval
;
}
for
(
i
=
new_driver
->
minor
;
i
<
new_driver
->
minor
+
new_driver
->
num_minors
;
++
i
)
usb_minors
[
i
]
=
new_driver
;
}
#endif
info
(
"registered new driver %s"
,
new_driver
->
name
);
...
...
@@ -96,9 +139,96 @@ int usb_register(struct usb_driver *new_driver)
usbfs_update_special
();
return
0
;
return
retval
;
}
/**
* usb_register_dev - register a USB device, and ask for a minor number
* @new_driver: USB operations for the driver
* @num_minors: number of minor numbers requested for this device
* @start_minor: place to put the new starting minor number
*
* Used to ask the USB core for a new minor number for a device that has
* just showed up. This is used to dynamically allocate minor numbers
* from the pool of USB reserved minor numbers.
*
* This should be called by all drivers that use the USB major number.
* This only returns a good value of CONFIG_USB_DYNAMIC_MINORS is
* selected by the user.
*
* usb_deregister_dev() should be called when the driver is done with
* the minor numbers given out by this function.
*
* Returns -ENODEV if CONFIG_USB_DYNAMIC_MINORS is not enabled in this
* kernel, -EINVAL if something bad happens with trying to register a
* device, and 0 on success, alone with a value that the driver should
* use in start_minor.
*/
#ifdef CONFIG_USB_DYNAMIC_MINORS
int
usb_register_dev
(
struct
usb_driver
*
new_driver
,
int
num_minors
,
int
*
start_minor
)
{
int
i
;
int
j
;
int
good_spot
;
int
retval
=
-
EINVAL
;
dbg
(
"%s is asking for %d minors"
,
new_driver
->
name
,
num_minors
);
if
(
new_driver
->
fops
==
NULL
)
goto
exit
;
*
start_minor
=
0
;
spin_lock
(
&
minor_lock
);
for
(
i
=
0
;
i
<
MAX_USB_MINORS
;
++
i
)
{
if
(
usb_minors
[
i
])
continue
;
good_spot
=
1
;
for
(
j
=
1
;
j
<=
num_minors
-
1
;
++
j
)
if
(
usb_minors
[
i
+
j
])
{
good_spot
=
0
;
break
;
}
if
(
good_spot
==
0
)
continue
;
*
start_minor
=
i
;
spin_unlock
(
&
minor_lock
);
retval
=
usb_register_minors
(
new_driver
,
num_minors
,
*
start_minor
);
if
(
retval
)
{
/* someone snuck in here, so let's start looking all over again */
spin_lock
(
&
minor_lock
);
i
=
0
;
continue
;
}
goto
exit
;
}
spin_unlock
(
&
minor_lock
);
exit:
return
retval
;
}
/**
* usb_deregister_dev - deregister a USB device's dynamic minor.
* @driver: USB operations for the driver
* @num_minors: number of minor numbers to put back.
* @start_minor: the starting minor number
*
* Used in conjunction with usb_register_dev(). This function is called
* when the USB driver is finished with the minor numbers gotten from a
* call to usb_register_dev() (usually when the device is disconnected
* from the system.)
*
* This should be called by all drivers that use the USB major number.
*/
void
usb_deregister_dev
(
struct
usb_driver
*
driver
,
int
num_minors
,
int
start_minor
)
{
usb_deregister_minors
(
driver
,
num_minors
,
start_minor
);
}
#endif
/* CONFIG_USB_DYNAMIC_MINORS */
/**
* usb_scan_devices - scans all unclaimed USB interfaces
* Context: !in_interrupt ()
...
...
@@ -177,12 +307,13 @@ static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev)
void
usb_deregister
(
struct
usb_driver
*
driver
)
{
struct
list_head
*
tmp
;
int
i
;
info
(
"deregistering driver %s"
,
driver
->
name
);
#ifndef CONFIG_USB_DYNAMIC_MINORS
if
(
driver
->
fops
!=
NULL
)
for
(
i
=
driver
->
minor
;
i
<
driver
->
minor
+
driver
->
num_minors
;
++
i
)
usb_minors
[
i
]
=
NULL
;
usb_deregister_minors
(
driver
,
driver
->
num_minors
,
driver
->
minor
);
#endif
/*
* first we remove the driver, to be sure it doesn't get used by
...
...
@@ -2524,14 +2655,14 @@ int usb_new_device(struct usb_device *dev)
static
int
usb_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
int
minor
=
minor
(
inode
->
i_rdev
);
struct
usb_driver
*
c
=
usb_minors
[
minor
]
;
struct
usb_driver
*
c
;
int
err
=
-
ENODEV
;
struct
file_operations
*
old_fops
,
*
new_fops
=
NULL
;
/*
* No load-on-demand? Randy, could you ACK that it's really not
* supposed to be done? -- AV
*/
spin_lock
(
&
minor_lock
);
c
=
usb_minors
[
minor
];
spin_unlock
(
&
minor_lock
);
if
(
!
c
||
!
(
new_fops
=
fops_get
(
c
->
fops
)))
return
err
;
old_fops
=
file
->
f_op
;
...
...
@@ -2623,9 +2754,13 @@ EXPORT_SYMBOL(usb_register);
EXPORT_SYMBOL
(
usb_deregister
);
EXPORT_SYMBOL
(
usb_scan_devices
);
#ifdef CONFIG_USB_DYNAMIC_MINORS
EXPORT_SYMBOL
(
usb_register_dev
);
EXPORT_SYMBOL
(
usb_deregister_dev
);
#endif
EXPORT_SYMBOL
(
usb_alloc_dev
);
EXPORT_SYMBOL
(
usb_free_dev
);
EXPORT_SYMBOL
(
usb_inc_dev_use
);
EXPORT_SYMBOL
(
usb_find_interface_driver_for_ifnum
);
EXPORT_SYMBOL
(
usb_driver_claim_interface
);
...
...
drivers/usb/host/ehci-hub.c
View file @
f0dbe47d
...
...
@@ -91,7 +91,10 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
if
(
!
(
temp
&
PORT_CONNECT
))
ehci
->
reset_done
[
i
]
=
0
;
if
((
temp
&
(
PORT_CSC
|
PORT_PEC
|
PORT_OCC
))
!=
0
)
{
set_bit
(
i
,
buf
);
if
(
i
<
7
)
buf
[
0
]
|=
1
<<
(
i
+
1
);
else
buf
[
1
]
|=
1
<<
(
i
-
7
);
status
=
STS_PCD
;
}
}
...
...
@@ -141,7 +144,7 @@ static int ehci_hub_control (
)
{
struct
ehci_hcd
*
ehci
=
hcd_to_ehci
(
hcd
);
int
ports
=
HCS_N_PORTS
(
ehci
->
hcs_params
);
u32
temp
;
u32
temp
,
status
;
unsigned
long
flags
;
int
retval
=
0
;
...
...
@@ -219,22 +222,22 @@ static int ehci_hub_control (
if
(
!
wIndex
||
wIndex
>
ports
)
goto
error
;
wIndex
--
;
memset
(
buf
,
0
,
4
)
;
status
=
0
;
temp
=
readl
(
&
ehci
->
regs
->
port_status
[
wIndex
]);
// wPortChange bits
if
(
temp
&
PORT_CSC
)
s
et_bit
(
USB_PORT_FEAT_C_CONNECTION
,
buf
)
;
s
tatus
|=
1
<<
USB_PORT_FEAT_C_CONNECTION
;
if
(
temp
&
PORT_PEC
)
s
et_bit
(
USB_PORT_FEAT_C_ENABLE
,
buf
)
;
s
tatus
|=
1
<<
USB_PORT_FEAT_C_ENABLE
;
// USB_PORT_FEAT_C_SUSPEND
if
(
temp
&
PORT_OCC
)
s
et_bit
(
USB_PORT_FEAT_C_OVER_CURRENT
,
buf
)
;
s
tatus
|=
1
<<
USB_PORT_FEAT_C_OVER_CURRENT
;
/* whoever resets must GetPortStatus to complete it!! */
if
((
temp
&
PORT_RESET
)
&&
jiffies
>
ehci
->
reset_done
[
wIndex
])
{
s
et_bit
(
USB_PORT_FEAT_C_RESET
,
buf
)
;
s
tatus
|=
1
<<
USB_PORT_FEAT_C_RESET
;
/* force reset to complete */
writel
(
temp
&
~
PORT_RESET
,
...
...
@@ -252,26 +255,27 @@ static int ehci_hub_control (
// don't show wPortStatus if it's owned by a companion hc
if
(
!
(
temp
&
PORT_OWNER
))
{
if
(
temp
&
PORT_CONNECT
)
{
s
et_bit
(
USB_PORT_FEAT_CONNECTION
,
buf
)
;
s
et_bit
(
USB_PORT_FEAT_HIGHSPEED
,
buf
)
;
s
tatus
|=
1
<<
USB_PORT_FEAT_CONNECTION
;
s
tatus
|=
1
<<
USB_PORT_FEAT_HIGHSPEED
;
}
if
(
temp
&
PORT_PE
)
s
et_bit
(
USB_PORT_FEAT_ENABLE
,
buf
)
;
s
tatus
|=
1
<<
USB_PORT_FEAT_ENABLE
;
if
(
temp
&
PORT_SUSPEND
)
s
et_bit
(
USB_PORT_FEAT_SUSPEND
,
buf
)
;
s
tatus
|=
1
<<
USB_PORT_FEAT_SUSPEND
;
if
(
temp
&
PORT_OC
)
s
et_bit
(
USB_PORT_FEAT_OVER_CURRENT
,
buf
)
;
s
tatus
|=
1
<<
USB_PORT_FEAT_OVER_CURRENT
;
if
(
temp
&
PORT_RESET
)
s
et_bit
(
USB_PORT_FEAT_RESET
,
buf
)
;
s
tatus
|=
1
<<
USB_PORT_FEAT_RESET
;
if
(
temp
&
PORT_POWER
)
s
et_bit
(
USB_PORT_FEAT_POWER
,
buf
)
;
s
tatus
|=
1
<<
USB_PORT_FEAT_POWER
;
}
#ifndef EHCI_VERBOSE_DEBUG
if
(
*
(
u16
*
)(
buf
+
2
)
)
/* only if wPortChange is interesting */
if
(
status
&
~
0xffff
)
/* only if wPortChange is interesting */
#endif
dbg_port
(
hcd
,
"GetStatus"
,
wIndex
+
1
,
temp
);
cpu_to_le32s
((
u32
*
)
buf
);
// we "know" this alignment is good, caller used kmalloc()...
*
((
u32
*
)
buf
)
=
cpu_to_le32
(
status
);
break
;
case
SetHubFeature
:
switch
(
wValue
)
{
...
...
drivers/usb/host/ohci-hub.c
View file @
f0dbe47d
...
...
@@ -96,7 +96,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
|
RH_PS_OCIC
|
RH_PS_PRSC
;
if
(
status
)
{
changed
=
1
;
set_bit
(
i
+
1
,
buf
);
if
(
i
<
7
)
buf
[
0
]
|=
1
<<
(
i
+
1
);
else
buf
[
1
]
|=
1
<<
(
i
-
7
);
}
}
return
changed
?
length
:
0
;
...
...
drivers/usb/image/mdc800.c
View file @
f0dbe47d
...
...
@@ -119,8 +119,12 @@
#define TO_READ_FROM_IRQ TO_DEFAULT_COMMAND
#define TO_GET_READY TO_DEFAULT_COMMAND
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define MDC800_DEVICE_MINOR_BASE 0
#else
/* Minor Number of the device (create with mknod /dev/mustek c 180 32) */
#define MDC800_DEVICE_MINOR_BASE 32
#endif
/**************************************************************************
...
...
@@ -176,6 +180,7 @@ struct mdc800_data
int
pic_index
;
// Cache for the Imagesize (-1 for nothing cached )
int
pic_len
;
int
minor
;
};
...
...
@@ -470,6 +475,8 @@ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum,
down
(
&
mdc800
->
io_lock
);
usb_register_dev
(
&
mdc800_usb_driver
,
1
,
&
mdc800
->
minor
);
mdc800
->
dev
=
dev
;
mdc800
->
open
=
0
;
...
...
@@ -525,6 +532,8 @@ static void mdc800_usb_disconnect (struct usb_device *dev,void* ptr)
if
(
mdc800
->
state
==
NOT_CONNECTED
)
return
;
usb_deregister_dev
(
&
mdc800_usb_driver
,
1
,
mdc800
->
minor
);
mdc800
->
state
=
NOT_CONNECTED
;
usb_unlink_urb
(
mdc800
->
irq_urb
);
...
...
drivers/usb/image/scanner.c
View file @
f0dbe47d
...
...
@@ -953,10 +953,12 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum,
down
(
&
scn_mutex
);
if
(
usb_register_dev
(
&
scanner_driver
,
1
,
&
scn_minor
))
{
for
(
scn_minor
=
0
;
scn_minor
<
SCN_MAX_MNR
;
scn_minor
++
)
{
if
(
!
p_scn_table
[
scn_minor
])
break
;
}
}
/* Check to make sure that the last slot isn't already taken */
if
(
p_scn_table
[
scn_minor
])
{
...
...
@@ -1086,6 +1088,7 @@ disconnect_scanner(struct usb_device *dev, void *ptr)
dbg
(
"disconnect_scanner: De-allocating minor:%d"
,
scn
->
scn_minor
);
devfs_unregister
(
scn
->
devfs
);
usb_deregister_dev
(
&
scanner_driver
,
1
,
scn
->
scn_minor
);
p_scn_table
[
scn
->
scn_minor
]
=
NULL
;
usb_free_urb
(
scn
->
scn_irq
);
up
(
&
(
scn
->
sem
));
...
...
drivers/usb/image/scanner.h
View file @
f0dbe47d
...
...
@@ -233,8 +233,13 @@ MODULE_DEVICE_TABLE (usb, scanner_device_ids);
#define SCANNER_IOCTL_CTRLMSG _IOWR('U', 0x22, struct usb_ctrlrequest)
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define SCN_MAX_MNR 256
#define SCN_BASE_MNR 0
#else
#define SCN_MAX_MNR 16
/* We're allocated 16 minors */
#define SCN_BASE_MNR 48
/* USB Scanners start at minor 48 */
#endif
static
DECLARE_MUTEX
(
scn_mutex
);
/* Initializes to unlocked */
...
...
drivers/usb/input/hid-core.c
View file @
f0dbe47d
...
...
@@ -1271,6 +1271,7 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_ATEN_UC100KM 0x2004
#define USB_DEVICE_ID_ATEN_CS124U 0x2202
#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204
#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205
struct
hid_blacklist
{
__u16
idVendor
;
...
...
@@ -1288,6 +1289,7 @@ struct hid_blacklist {
{
USB_VENDOR_ID_ATEN
,
USB_DEVICE_ID_ATEN_UC100KM
,
HID_QUIRK_NOGET
},
{
USB_VENDOR_ID_ATEN
,
USB_DEVICE_ID_ATEN_CS124U
,
HID_QUIRK_NOGET
},
{
USB_VENDOR_ID_ATEN
,
USB_DEVICE_ID_ATEN_2PORTKVM
,
HID_QUIRK_NOGET
},
{
USB_VENDOR_ID_ATEN
,
USB_DEVICE_ID_ATEN_4PORTKVM
,
HID_QUIRK_NOGET
},
{
0
,
0
}
};
...
...
drivers/usb/input/hiddev.c
View file @
f0dbe47d
...
...
@@ -25,10 +25,7 @@
* e-mail - mail your message to Paul Stewart <stewart@wetlogic.net>
*/
#define HIDDEV_MINOR_BASE 96
#define HIDDEV_MINORS 16
#define HIDDEV_BUFFER_SIZE 64
#include <linux/config.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/module.h>
...
...
@@ -39,6 +36,15 @@
#include "hid.h"
#include <linux/hiddev.h>
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define HIDDEV_MINOR_BASE 0
#define HIDDEV_MINORS 256
#else
#define HIDDEV_MINOR_BASE 96
#define HIDDEV_MINORS 16
#endif
#define HIDDEV_BUFFER_SIZE 64
struct
hiddev
{
int
exist
;
int
open
;
...
...
@@ -62,6 +68,9 @@ struct hiddev_list {
static
struct
hiddev
*
hiddev_table
[
HIDDEV_MINORS
];
static
devfs_handle_t
hiddev_devfs_handle
;
/* forward reference to make our lives easier */
extern
struct
usb_driver
hiddev_driver
;
/*
* Find a report, given the report's type and ID. The ID can be specified
* indirectly by REPORT_ID_FIRST (which returns the first report of the given
...
...
@@ -184,6 +193,7 @@ static int hiddev_fasync(int fd, struct file *file, int on)
static
void
hiddev_cleanup
(
struct
hiddev
*
hiddev
)
{
devfs_unregister
(
hiddev
->
devfs
);
usb_deregister_dev
(
&
hiddev_driver
,
1
,
hiddev
->
minor
);
hiddev_table
[
hiddev
->
minor
]
=
NULL
;
kfree
(
hiddev
);
}
...
...
@@ -605,11 +615,13 @@ int hiddev_connect(struct hid_device *hid)
if
(
i
==
hid
->
maxapplication
)
return
-
1
;
if
(
usb_register_dev
(
&
hiddev_driver
,
1
,
&
minor
))
{
for
(
minor
=
0
;
minor
<
HIDDEV_MINORS
&&
hiddev_table
[
minor
];
minor
++
);
if
(
minor
==
HIDDEV_MINORS
)
{
printk
(
KERN_ERR
"hiddev: no more free hiddev devices
\n
"
);
return
-
1
;
}
}
if
(
!
(
hiddev
=
kmalloc
(
sizeof
(
struct
hiddev
),
GFP_KERNEL
)))
return
-
1
;
...
...
drivers/usb/media/Makefile
View file @
f0dbe47d
...
...
@@ -4,7 +4,7 @@
O_TARGET
:=
media.o
export-objs
:=
ov511.o pwc-uncompress.o
export-objs
:=
ov511.o pwc-uncompress.o
usbvideo.o
pwc-objs
:=
pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o
...
...
drivers/usb/media/dabusb.c
View file @
f0dbe47d
...
...
@@ -52,12 +52,17 @@
/* --------------------------------------------------------------------- */
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define NRDABUSB 256
#else
#define NRDABUSB 4
#endif
/*-------------------------------------------------------------------*/
static
dabusb_t
dabusb
[
NRDABUSB
];
static
int
buffers
=
256
;
extern
struct
usb_driver
dabusb_driver
;
/*-------------------------------------------------------------------*/
...
...
@@ -734,15 +739,18 @@ static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum,
if
(
ifnum
!=
_DABUSB_IF
&&
usbdev
->
descriptor
.
idProduct
==
0x9999
)
return
NULL
;
if
(
usb_register_dev
(
&
dabusb_driver
,
1
,
&
devnum
))
{
devnum
=
dabusb_find_struct
();
if
(
devnum
==
-
1
)
return
NULL
;
}
s
=
&
dabusb
[
devnum
];
down
(
&
s
->
mutex
);
s
->
remove_pending
=
0
;
s
->
usbdev
=
usbdev
;
s
->
devnum
=
devnum
;
if
(
usb_set_configuration
(
usbdev
,
usbdev
->
config
[
0
].
bConfigurationValue
)
<
0
)
{
err
(
"set_configuration failed"
);
...
...
@@ -777,6 +785,7 @@ static void dabusb_disconnect (struct usb_device *usbdev, void *ptr)
dbg
(
"dabusb_disconnect"
);
usb_deregister_dev
(
&
dabusb_driver
,
1
,
s
->
devnum
);
s
->
remove_pending
=
1
;
wake_up
(
&
s
->
wait
);
if
(
s
->
state
==
_started
)
...
...
drivers/usb/media/dabusb.h
View file @
f0dbe47d
...
...
@@ -6,7 +6,11 @@ typedef struct
unsigned
int
pipe
;
}
bulk_transfer_t
,
*
pbulk_transfer_t
;
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define DABUSB_MINOR 0
#else
#define DABUSB_MINOR 240
/* some unassigned USB minor */
#endif
#define DABUSB_VERSION 0x1000
#define IOCTL_DAB_BULK _IOWR('d', 0x30, bulk_transfer_t)
#define IOCTL_DAB_OVERRUNS _IOR('d', 0x15, int)
...
...
@@ -31,6 +35,7 @@ typedef struct
unsigned
int
overruns
;
int
readptr
;
int
opened
;
int
devnum
;
struct
list_head
free_buff_list
;
struct
list_head
rec_buff_list
;
}
dabusb_t
,
*
pdabusb_t
;
...
...
drivers/usb/media/usbvideo.c
View file @
f0dbe47d
...
...
@@ -18,7 +18,6 @@
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/slab.h>
#define __NO_VERSION__
/* Temporary: usbvideo is not a module yet */
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/smp_lock.h>
...
...
@@ -55,6 +54,24 @@ static int usbvideo_default_procfs_write_proc(
unsigned
long
count
,
void
*
data
);
#endif
static
void
usbvideo_Disconnect
(
struct
usb_device
*
dev
,
void
*
ptr
);
static
void
usbvideo_CameraRelease
(
uvd_t
*
uvd
);
static
int
usbvideo_v4l_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
);
static
int
usbvideo_v4l_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
);
static
int
usbvideo_v4l_open
(
struct
inode
*
inode
,
struct
file
*
file
);
static
int
usbvideo_v4l_read
(
struct
file
*
file
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
);
static
int
usbvideo_v4l_close
(
struct
inode
*
inode
,
struct
file
*
file
);
static
int
usbvideo_StartDataPump
(
uvd_t
*
uvd
);
static
void
usbvideo_StopDataPump
(
uvd_t
*
uvd
);
static
int
usbvideo_GetFrame
(
uvd_t
*
uvd
,
int
frameNum
);
static
int
usbvideo_NewFrame
(
uvd_t
*
uvd
,
int
framenum
);
static
void
usbvideo_SoftwareContrastAdjustment
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
);
/*******************************/
/* Memory management functions */
/*******************************/
...
...
@@ -73,7 +90,7 @@ unsigned long usbvideo_kvirt_to_pa(unsigned long adr)
return
ret
;
}
void
*
usbvideo_rvmalloc
(
unsigned
long
size
)
static
void
*
usbvideo_rvmalloc
(
unsigned
long
size
)
{
void
*
mem
;
unsigned
long
adr
;
...
...
@@ -94,7 +111,7 @@ void *usbvideo_rvmalloc(unsigned long size)
return
mem
;
}
void
usbvideo_rvfree
(
void
*
mem
,
unsigned
long
size
)
static
void
usbvideo_rvfree
(
void
*
mem
,
unsigned
long
size
)
{
unsigned
long
adr
;
...
...
@@ -110,13 +127,13 @@ void usbvideo_rvfree(void *mem, unsigned long size)
vfree
(
mem
);
}
void
RingQueue_Initialize
(
RingQueue_t
*
rq
)
static
void
RingQueue_Initialize
(
RingQueue_t
*
rq
)
{
assert
(
rq
!=
NULL
);
init_waitqueue_head
(
&
rq
->
wqh
);
}
void
RingQueue_Allocate
(
RingQueue_t
*
rq
,
int
rqLen
)
static
void
RingQueue_Allocate
(
RingQueue_t
*
rq
,
int
rqLen
)
{
assert
(
rq
!=
NULL
);
assert
(
rqLen
>
0
);
...
...
@@ -125,14 +142,14 @@ void RingQueue_Allocate(RingQueue_t *rq, int rqLen)
assert
(
rq
->
queue
!=
NULL
);
}
int
RingQueue_IsAllocated
(
const
RingQueue_t
*
rq
)
static
int
RingQueue_IsAllocated
(
const
RingQueue_t
*
rq
)
{
if
(
rq
==
NULL
)
return
0
;
return
(
rq
->
queue
!=
NULL
)
&&
(
rq
->
length
>
0
);
}
void
RingQueue_Free
(
RingQueue_t
*
rq
)
static
void
RingQueue_Free
(
RingQueue_t
*
rq
)
{
assert
(
rq
!=
NULL
);
if
(
RingQueue_IsAllocated
(
rq
))
{
...
...
@@ -154,6 +171,8 @@ int RingQueue_Dequeue(RingQueue_t *rq, unsigned char *dst, int len)
return
len
;
}
EXPORT_SYMBOL
(
RingQueue_Dequeue
);
int
RingQueue_Enqueue
(
RingQueue_t
*
rq
,
const
unsigned
char
*
cdata
,
int
n
)
{
int
enqueued
=
0
;
...
...
@@ -184,6 +203,8 @@ int RingQueue_Enqueue(RingQueue_t *rq, const unsigned char *cdata, int n)
return
enqueued
;
}
EXPORT_SYMBOL
(
RingQueue_Enqueue
);
int
RingQueue_GetLength
(
const
RingQueue_t
*
rq
)
{
int
ri
,
wi
;
...
...
@@ -200,7 +221,9 @@ int RingQueue_GetLength(const RingQueue_t *rq)
return
wi
+
(
rq
->
length
-
ri
);
}
void
RingQueue_InterruptibleSleepOn
(
RingQueue_t
*
rq
)
EXPORT_SYMBOL
(
RingQueue_GetLength
);
static
void
RingQueue_InterruptibleSleepOn
(
RingQueue_t
*
rq
)
{
assert
(
rq
!=
NULL
);
interruptible_sleep_on
(
&
rq
->
wqh
);
...
...
@@ -213,6 +236,8 @@ void RingQueue_WakeUpInterruptible(RingQueue_t *rq)
wake_up_interruptible
(
&
rq
->
wqh
);
}
EXPORT_SYMBOL
(
RingQueue_WakeUpInterruptible
);
/*
* usbvideo_VideosizeToString()
*
...
...
@@ -222,7 +247,7 @@ void RingQueue_WakeUpInterruptible(RingQueue_t *rq)
* 07-Aug-2000 Created.
* 19-Oct-2000 Reworked for usbvideo module.
*/
void
usbvideo_VideosizeToString
(
char
*
buf
,
int
bufLen
,
videosize_t
vs
)
static
void
usbvideo_VideosizeToString
(
char
*
buf
,
int
bufLen
,
videosize_t
vs
)
{
char
tmp
[
40
];
int
n
;
...
...
@@ -241,7 +266,7 @@ void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs)
* History:
* 01-Feb-2000 Created.
*/
void
usbvideo_OverlayChar
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
,
static
void
usbvideo_OverlayChar
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
,
int
x
,
int
y
,
int
ch
)
{
static
const
unsigned
short
digits
[
16
]
=
{
...
...
@@ -296,7 +321,7 @@ void usbvideo_OverlayChar(uvd_t *uvd, usbvideo_frame_t *frame,
* History:
* 01-Feb-2000 Created.
*/
void
usbvideo_OverlayString
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
,
static
void
usbvideo_OverlayString
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
,
int
x
,
int
y
,
const
char
*
str
)
{
while
(
*
str
)
{
...
...
@@ -314,7 +339,7 @@ void usbvideo_OverlayString(uvd_t *uvd, usbvideo_frame_t *frame,
* History:
* 01-Feb-2000 Created.
*/
void
usbvideo_OverlayStats
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
)
static
void
usbvideo_OverlayStats
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
)
{
const
int
y_diff
=
8
;
char
tmp
[
16
];
...
...
@@ -437,7 +462,7 @@ void usbvideo_OverlayStats(uvd_t *uvd, usbvideo_frame_t *frame)
* History:
* 14-Jan-2000 Corrected default multiplier.
*/
void
usbvideo_ReportStatistics
(
const
uvd_t
*
uvd
)
static
void
usbvideo_ReportStatistics
(
const
uvd_t
*
uvd
)
{
if
((
uvd
!=
NULL
)
&&
(
uvd
->
stats
.
urb_count
>
0
))
{
unsigned
long
allPackets
,
badPackets
,
goodPackets
,
percent
;
...
...
@@ -549,6 +574,8 @@ void usbvideo_DrawLine(
}
}
EXPORT_SYMBOL
(
usbvideo_DrawLine
);
/*
* usbvideo_TestPattern()
*
...
...
@@ -636,6 +663,8 @@ void usbvideo_TestPattern(uvd_t *uvd, int fullframe, int pmode)
usbvideo_OverlayStats
(
uvd
,
frame
);
}
EXPORT_SYMBOL
(
usbvideo_TestPattern
);
/*
* usbvideo_HexDump()
*
...
...
@@ -663,6 +692,8 @@ void usbvideo_HexDump(const unsigned char *data, int len)
printk
(
"%s
\n
"
,
tmp
);
}
EXPORT_SYMBOL
(
usbvideo_HexDump
);
/* Debugging aid */
void
usbvideo_SayAndWait
(
const
char
*
what
)
{
...
...
@@ -672,6 +703,8 @@ void usbvideo_SayAndWait(const char *what)
interruptible_sleep_on_timeout
(
&
wq
,
HZ
*
3
);
/* Timeout */
}
EXPORT_SYMBOL
(
usbvideo_SayAndWait
);
/* ******************************************************************** */
static
void
usbvideo_ClientIncModCount
(
uvd_t
*
uvd
)
...
...
@@ -825,6 +858,8 @@ int usbvideo_register(
return
0
;
}
EXPORT_SYMBOL
(
usbvideo_register
);
/*
* usbvideo_Deregister()
*
...
...
@@ -886,6 +921,8 @@ void usbvideo_Deregister(usbvideo_t **pCams)
*
pCams
=
NULL
;
}
EXPORT_SYMBOL
(
usbvideo_Deregister
);
/*
* usbvideo_Disconnect()
*
...
...
@@ -908,7 +945,7 @@ void usbvideo_Deregister(usbvideo_t **pCams)
* 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
* 19-Oct-2000 Moved to usbvideo module.
*/
void
usbvideo_Disconnect
(
struct
usb_device
*
dev
,
void
*
ptr
)
static
void
usbvideo_Disconnect
(
struct
usb_device
*
dev
,
void
*
ptr
)
{
static
const
char
proc
[]
=
"usbvideo_Disconnect"
;
uvd_t
*
uvd
=
(
uvd_t
*
)
ptr
;
...
...
@@ -958,7 +995,7 @@ void usbvideo_Disconnect(struct usb_device *dev, void *ptr)
* History:
* 27-Jan-2000 Created.
*/
void
usbvideo_CameraRelease
(
uvd_t
*
uvd
)
static
void
usbvideo_CameraRelease
(
uvd_t
*
uvd
)
{
static
const
char
proc
[]
=
"usbvideo_CameraRelease"
;
if
(
uvd
==
NULL
)
{
...
...
@@ -1079,6 +1116,8 @@ uvd_t *usbvideo_AllocateDevice(usbvideo_t *cams)
return
uvd
;
}
EXPORT_SYMBOL
(
usbvideo_AllocateDevice
);
int
usbvideo_RegisterVideoDevice
(
uvd_t
*
uvd
)
{
static
const
char
proc
[]
=
"usbvideo_RegisterVideoDevice"
;
...
...
@@ -1139,9 +1178,11 @@ int usbvideo_RegisterVideoDevice(uvd_t *uvd)
return
0
;
}
EXPORT_SYMBOL
(
usbvideo_RegisterVideoDevice
);
/* ******************************************************************** */
int
usbvideo_v4l_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
static
int
usbvideo_v4l_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
{
uvd_t
*
uvd
=
file
->
private_data
;
unsigned
long
start
=
vma
->
vm_start
;
...
...
@@ -1185,7 +1226,7 @@ int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma)
* 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
* 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
*/
int
usbvideo_v4l_open
(
struct
inode
*
inode
,
struct
file
*
file
)
static
int
usbvideo_v4l_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
static
const
char
proc
[]
=
"usbvideo_v4l_open"
;
struct
video_device
*
dev
=
video_devdata
(
file
);
...
...
@@ -1300,7 +1341,7 @@ int usbvideo_v4l_open(struct inode *inode, struct file *file)
* 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
* 24-May-2000 Moved MOD_DEC_USE_COUNT outside of code that can sleep.
*/
int
usbvideo_v4l_close
(
struct
inode
*
inode
,
struct
file
*
file
)
static
int
usbvideo_v4l_close
(
struct
inode
*
inode
,
struct
file
*
file
)
{
static
const
char
proc
[]
=
"usbvideo_v4l_close"
;
struct
video_device
*
dev
=
file
->
private_data
;
...
...
@@ -1554,7 +1595,7 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file,
return
0
;
}
int
usbvideo_v4l_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
static
int
usbvideo_v4l_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
return
video_usercopy
(
inode
,
file
,
cmd
,
arg
,
usbvideo_v4l_do_ioctl
);
...
...
@@ -1571,7 +1612,7 @@ int usbvideo_v4l_ioctl(struct inode *inode, struct file *file,
* 20-Oct-2000 Created.
* 01-Nov-2000 Added mutex (uvd->lock).
*/
int
usbvideo_v4l_read
(
struct
file
*
file
,
char
*
buf
,
static
int
usbvideo_v4l_read
(
struct
file
*
file
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
static
const
char
proc
[]
=
"usbvideo_v4l_read"
;
...
...
@@ -1809,7 +1850,7 @@ static void usbvideo_IsocIrq(struct urb *urb)
* of hardcoded values. Simplified by using for loop,
* allowed any number of URBs.
*/
int
usbvideo_StartDataPump
(
uvd_t
*
uvd
)
static
int
usbvideo_StartDataPump
(
uvd_t
*
uvd
)
{
static
const
char
proc
[]
=
"usbvideo_StartDataPump"
;
struct
usb_device
*
dev
=
uvd
->
dev
;
...
...
@@ -1885,7 +1926,7 @@ int usbvideo_StartDataPump(uvd_t *uvd)
* 22-Jan-2000 Corrected order of actions to work after surprise removal.
* 27-Jan-2000 Used uvd->iface, uvd->ifaceAltInactive instead of hardcoded values.
*/
void
usbvideo_StopDataPump
(
uvd_t
*
uvd
)
static
void
usbvideo_StopDataPump
(
uvd_t
*
uvd
)
{
static
const
char
proc
[]
=
"usbvideo_StopDataPump"
;
int
i
,
j
;
...
...
@@ -1929,7 +1970,7 @@ void usbvideo_StopDataPump(uvd_t *uvd)
* 29-Mar-00 Added copying of previous frame into the current one.
* 6-Aug-00 Added model 3 video sizes, removed redundant width, height.
*/
int
usbvideo_NewFrame
(
uvd_t
*
uvd
,
int
framenum
)
static
int
usbvideo_NewFrame
(
uvd_t
*
uvd
,
int
framenum
)
{
usbvideo_frame_t
*
frame
;
int
n
;
...
...
@@ -2004,7 +2045,7 @@ int usbvideo_NewFrame(uvd_t *uvd, int framenum)
* FLAGS_NO_DECODING set. Therefore, any regular build of any driver
* based on usbvideo can use this feature at any time.
*/
void
usbvideo_CollectRawData
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
)
static
void
usbvideo_CollectRawData
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
)
{
int
n
;
...
...
@@ -2034,7 +2075,7 @@ void usbvideo_CollectRawData(uvd_t *uvd, usbvideo_frame_t *frame)
}
}
int
usbvideo_GetFrame
(
uvd_t
*
uvd
,
int
frameNum
)
static
int
usbvideo_GetFrame
(
uvd_t
*
uvd
,
int
frameNum
)
{
static
const
char
proc
[]
=
"usbvideo_GetFrame"
;
usbvideo_frame_t
*
frame
=
&
uvd
->
frame
[
frameNum
];
...
...
@@ -2225,6 +2266,8 @@ void usbvideo_DeinterlaceFrame(uvd_t *uvd, usbvideo_frame_t *frame)
usbvideo_OverlayStats
(
uvd
,
frame
);
}
EXPORT_SYMBOL
(
usbvideo_DeinterlaceFrame
);
/*
* usbvideo_SoftwareContrastAdjustment()
*
...
...
@@ -2235,7 +2278,8 @@ void usbvideo_DeinterlaceFrame(uvd_t *uvd, usbvideo_frame_t *frame)
* History:
* 09-Feb-2001 Created.
*/
void
usbvideo_SoftwareContrastAdjustment
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
)
static
void
usbvideo_SoftwareContrastAdjustment
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
)
{
static
const
char
proc
[]
=
"usbvideo_SoftwareContrastAdjustment"
;
int
i
,
j
,
v4l_linesize
;
...
...
drivers/usb/media/usbvideo.h
View file @
f0dbe47d
...
...
@@ -304,35 +304,22 @@ typedef struct s_usbvideo_t usbvideo_t;
#define VALID_CALLBACK(uvd,cbName) ((((uvd) != NULL) && \
((uvd)->handle != NULL)) ? GET_CALLBACK(uvd,cbName) : NULL)
void
RingQueue_Initialize
(
RingQueue_t
*
rq
);
void
RingQueue_Allocate
(
RingQueue_t
*
rq
,
int
rqLen
);
int
RingQueue_IsAllocated
(
const
RingQueue_t
*
rq
);
void
RingQueue_Free
(
RingQueue_t
*
rq
);
int
RingQueue_Dequeue
(
RingQueue_t
*
rq
,
unsigned
char
*
dst
,
int
len
);
int
RingQueue_Enqueue
(
RingQueue_t
*
rq
,
const
unsigned
char
*
cdata
,
int
n
);
int
RingQueue_GetLength
(
const
RingQueue_t
*
rq
);
void
RingQueue_InterruptibleSleepOn
(
RingQueue_t
*
rq
);
void
RingQueue_WakeUpInterruptible
(
RingQueue_t
*
rq
);
void
usbvideo_CollectRawData
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
);
void
usbvideo_DrawLine
(
usbvideo_frame_t
*
frame
,
int
x1
,
int
y1
,
int
x2
,
int
y2
,
unsigned
char
cr
,
unsigned
char
cg
,
unsigned
char
cb
);
void
usbvideo_HexDump
(
const
unsigned
char
*
data
,
int
len
);
void
usbvideo_OverlayChar
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
,
int
x
,
int
y
,
int
ch
);
void
usbvideo_OverlayString
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
,
int
x
,
int
y
,
const
char
*
str
);
void
usbvideo_OverlayStats
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
);
void
usbvideo_ReportStatistics
(
const
uvd_t
*
uvd
);
void
usbvideo_SayAndWait
(
const
char
*
what
);
void
usbvideo_TestPattern
(
uvd_t
*
uvd
,
int
fullframe
,
int
pmode
);
void
usbvideo_VideosizeToString
(
char
*
buf
,
int
bufLen
,
videosize_t
vs
);
/* Memory allocation routines */
unsigned
long
usbvideo_kvirt_to_pa
(
unsigned
long
adr
);
void
*
usbvideo_rvmalloc
(
unsigned
long
size
);
void
usbvideo_rvfree
(
void
*
mem
,
unsigned
long
size
);
int
usbvideo_register
(
usbvideo_t
**
pCams
,
...
...
@@ -344,24 +331,10 @@ int usbvideo_register(
uvd_t
*
usbvideo_AllocateDevice
(
usbvideo_t
*
cams
);
int
usbvideo_RegisterVideoDevice
(
uvd_t
*
uvd
);
void
usbvideo_Deregister
(
usbvideo_t
**
uvt
);
void
usbvideo_Disconnect
(
struct
usb_device
*
dev
,
void
*
ptr
);
void
usbvideo_CameraRelease
(
uvd_t
*
uvd
);
int
usbvideo_v4l_close
(
struct
inode
*
inode
,
struct
file
*
file
);
int
usbvideo_v4l_initialize
(
struct
video_device
*
dev
);
int
usbvideo_v4l_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
);
int
usbvideo_v4l_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
);
int
usbvideo_v4l_open
(
struct
inode
*
inode
,
struct
file
*
file
);
int
usbvideo_v4l_read
(
struct
file
*
file
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
);
int
usbvideo_GetFrame
(
uvd_t
*
uvd
,
int
frameNum
);
int
usbvideo_NewFrame
(
uvd_t
*
uvd
,
int
framenum
);
int
usbvideo_StartDataPump
(
uvd_t
*
uvd
);
void
usbvideo_StopDataPump
(
uvd_t
*
uvd
);
void
usbvideo_DeinterlaceFrame
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
);
void
usbvideo_SoftwareContrastAdjustment
(
uvd_t
*
uvd
,
usbvideo_frame_t
*
frame
);
/*
* This code performs bounds checking - use it when working with
...
...
drivers/usb/misc/auerswald.c
View file @
f0dbe47d
...
...
@@ -60,12 +60,17 @@ do { \
/* Auerswald Vendor ID */
#define ID_AUERSWALD 0x09BF
#ifndef AUER_MINOR_BASE
/* allow external override */
#ifdef CONFIG_USB_DYNAMIC_MINORS
/* we can have up to 256 devices at once */
#define AUER_MINOR_BASE 0
#define AUER_MAX_DEVICES 256
#else
#define AUER_MINOR_BASE 112
/* auerswald driver minor number */
#endif
/* we can have up to this number of device plugged in at once */
#define AUER_MAX_DEVICES 16
#endif
/* prefix for the device descriptors in /dev/usb */
#define AU_PREFIX "auer"
...
...
@@ -284,6 +289,7 @@ typedef struct
/* Forwards */
static
void
auerswald_ctrlread_complete
(
struct
urb
*
urb
);
static
void
auerswald_removeservice
(
pauerswald_t
cp
,
pauerscon_t
scp
);
extern
struct
usb_driver
auerswald_driver
;
/*-------------------------------------------------------------------*/
...
...
@@ -1941,8 +1947,9 @@ static void *auerswald_probe (struct usb_device *usbdev, unsigned int ifnum,
auerbuf_init
(
&
cp
->
bufctl
);
init_waitqueue_head
(
&
cp
->
bufferwait
);
/* find a free slot in the device table */
down
(
&
dev_table_mutex
);
if
(
usb_register_dev
(
&
auerswald_driver
,
1
,
&
dtindex
))
{
/* find a free slot in the device table */
for
(
dtindex
=
0
;
dtindex
<
AUER_MAX_DEVICES
;
++
dtindex
)
{
if
(
dev_table
[
dtindex
]
==
NULL
)
break
;
...
...
@@ -1952,6 +1959,7 @@ static void *auerswald_probe (struct usb_device *usbdev, unsigned int ifnum,
up
(
&
dev_table_mutex
);
goto
pfail
;
}
}
/* Give the device a name */
sprintf
(
cp
->
name
,
AU_PREFIX
"%d"
,
dtindex
);
...
...
@@ -2081,6 +2089,9 @@ static void auerswald_disconnect (struct usb_device *usbdev, void *driver_contex
/* Nobody can see this device any more */
devfs_unregister
(
cp
->
devfs
);
/* give back our USB minor number */
usb_deregister_dev
(
&
auerswald_driver
,
1
,
cp
->
dtindex
);
/* Stop the interrupt endpoint */
auerswald_int_release
(
cp
);
...
...
@@ -2181,6 +2192,7 @@ static void __exit auerswald_cleanup (void)
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
"GPL"
);
module_init
(
auerswald_init
);
module_exit
(
auerswald_cleanup
);
...
...
drivers/usb/misc/brlvger.c
View file @
f0dbe47d
...
...
@@ -315,6 +315,7 @@ brlvger_probe (struct usb_device *dev, unsigned ifnum,
down
(
&
reserve_sem
);
if
(
usb_register_dev
(
&
brlvger_driver
,
1
,
&
i
))
{
for
(
i
=
0
;
i
<
MAX_NR_BRLVGER_DEVS
;
i
++
)
if
(
display_table
[
i
]
==
NULL
)
break
;
...
...
@@ -324,6 +325,7 @@ brlvger_probe (struct usb_device *dev, unsigned ifnum,
"braille displays"
,
MAX_NR_BRLVGER_DEVS
);
goto
error
;
}
}
if
(
!
(
priv
=
kmalloc
(
sizeof
*
priv
,
GFP_KERNEL
))
){
err
(
"No more memory"
);
...
...
@@ -423,6 +425,7 @@ brlvger_disconnect(struct usb_device *dev, void *ptr)
info
(
"Display %d disconnecting"
,
priv
->
subminor
);
devfs_unregister
(
priv
->
devfs
);
usb_deregister_dev
(
&
brlvger_driver
,
1
,
priv
->
subminor
);
down
(
&
disconnect_sem
);
display_table
[
priv
->
subminor
]
=
NULL
;
...
...
drivers/usb/net/pegasus.h
View file @
f0dbe47d
...
...
@@ -255,6 +255,8 @@ PEGASUS_DEV( "SMC 2206 USB Ethernet", VENDOR_SMC, 0x0201,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"SOHOware NUB100 Ethernet"
,
VENDOR_SOHOWARE
,
0x9100
,
DEFAULT_GPIO_RESET
)
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
)
...
...
drivers/usb/net/usbnet.c
View file @
f0dbe47d
...
...
@@ -121,7 +121,7 @@
#define CONFIG_USB_PL2301
#define DRIVER_VERSION "
0
6-Apr-2002"
#define DRIVER_VERSION "
2
6-Apr-2002"
/*-------------------------------------------------------------------------*/
...
...
@@ -484,14 +484,6 @@ static int genelink_free (struct usbnet *dev)
return
0
;
}
#else
static
int
genelink_check_connect
(
struct
usbnet
*
dev
)
{
dbg
(
"%s: assuming peer is connected"
,
dev
->
net
.
name
);
return
0
;
}
#endif
// reset the device status
...
...
@@ -623,12 +615,15 @@ static const struct driver_info genelink_info = {
description:
"Genesys GeneLink"
,
flags:
FLAG_FRAMING_GL
|
FLAG_NO_SETINT
,
reset:
genelink_reset
,
check_connect:
genelink_check_connect
,
rx_fixup:
genelink_rx_fixup
,
tx_fixup:
genelink_tx_fixup
,
in:
1
,
out
:
2
,
epsize:
64
,
#ifdef GENELINK_ACK
check_connect:
genelink_check_connect
,
#endif
};
#endif
/* CONFIG_USB_GENESYS */
...
...
@@ -652,11 +647,15 @@ static const struct driver_info genelink_info = {
*
*-------------------------------------------------------------------------*/
static
int
linuxdev_check_connect
(
struct
usbnet
*
dev
)
{
return
0
;
// by definition, always connected
}
static
const
struct
driver_info
linuxdev_info
=
{
description:
"Linux Device"
,
// no reset defined (yet?)
// no check_connect needed!
check_connect:
linuxdev_check_connect
,
in:
2
,
out
:
1
,
epsize:
64
,
};
...
...
@@ -1169,21 +1168,11 @@ static int pl_reset (struct usbnet *dev)
PL_S_EN
|
PL_RESET_OUT
|
PL_RESET_IN
|
PL_PEER_E
);
}
static
int
pl_check_connect
(
struct
usbnet
*
dev
)
{
// FIXME test interrupt data PL_PEER_E bit
// plus, there's some handshake done by
// the prolific win32 driver...
dbg
(
"%s: assuming peer is connected"
,
dev
->
net
.
name
);
return
0
;
}
static
const
struct
driver_info
prolific_info
=
{
description:
"Prolific PL-2301/PL-2302"
,
flags:
FLAG_NO_SETINT
,
/* some PL-2302 versions seem to fail usb_set_interface() */
reset:
pl_reset
,
check_connect:
pl_check_connect
,
in:
3
,
out
:
2
,
epsize:
64
,
...
...
@@ -1567,7 +1556,7 @@ static int usbnet_ethtool_ioctl (struct net_device *net, void *useraddr)
if
(
dev
->
driver_info
->
check_connect
)
{
struct
ethtool_value
edata
=
{
ETHTOOL_GLINK
};
edata
.
data
=
dev
->
driver_info
->
check_connect
(
dev
);
edata
.
data
=
dev
->
driver_info
->
check_connect
(
dev
)
==
0
;
if
(
copy_to_user
(
useraddr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
...
...
drivers/usb/serial/keyspan.c
View file @
f0dbe47d
...
...
@@ -28,6 +28,14 @@
Change History
Wed Apr 25 12:00:00 PST 2002 (Keyspan)
Started with Hugh Blemings' code dated Jan 17, 2002. All adapters
now supported (including QI and QW). Modified port open, port
close, and send setup() logic to fix various data and endpoint
synchronization bugs and device LED status bugs. Changed keyspan_
write_room() to accurately return transmit buffer availability.
Changed forwardingLength from 1 to 16 for all adapters.
Fri Oct 12 16:45:00 EST 2001
Preliminary USA-19QI and USA-28 support (both test OK for me, YMMV)
...
...
@@ -98,7 +106,7 @@
/*
* Version Information
*/
#define DRIVER_VERSION "v1.1.
2
"
#define DRIVER_VERSION "v1.1.
3
"
#define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu"
#define DRIVER_DESC "Keyspan USB to Serial Converter Driver"
...
...
@@ -423,6 +431,7 @@ static void usa26_indat_callback(struct urb *urb)
/* Resubmit urb so we continue receiving */
urb
->
dev
=
port
->
serial
->
dev
;
if
(
port
->
open_count
)
if
((
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
))
!=
0
)
{
dbg
(
"%s - resubmit read urb failed. (%d)"
,
__FUNCTION__
,
err
);
}
...
...
@@ -461,7 +470,7 @@ static void usa26_outcont_callback(struct urb *urb)
if
(
p_priv
->
resend_cont
)
{
dbg
(
"%s - sending setup"
,
__FUNCTION__
);
keyspan_usa26_send_setup
(
port
->
serial
,
port
,
0
);
keyspan_usa26_send_setup
(
port
->
serial
,
port
,
p_priv
->
resend_cont
-
1
);
}
}
...
...
@@ -519,12 +528,12 @@ static void usa26_instat_callback(struct urb *urb)
/* wake_up_interruptible(&p_priv->open_wait); */
}
exit:
/* Resubmit urb so we continue receiving */
urb
->
dev
=
serial
->
dev
;
if
((
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
))
!=
0
)
{
dbg
(
"%s - resubmit read urb failed. (%d)"
,
__FUNCTION__
,
err
);
}
exit:
}
static
void
usa26_glocont_callback
(
struct
urb
*
urb
)
...
...
@@ -572,6 +581,7 @@ static void usa28_indat_callback(struct urb *urb)
/* Resubmit urb so we continue receiving */
urb
->
dev
=
port
->
serial
->
dev
;
if
(
port
->
open_count
)
if
((
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
))
!=
0
)
{
dbg
(
"%s - resubmit read urb failed. (%d)"
,
__FUNCTION__
,
err
);
}
...
...
@@ -596,7 +606,7 @@ static void usa28_outcont_callback(struct urb *urb)
if
(
p_priv
->
resend_cont
)
{
dbg
(
"%s - sending setup"
,
__FUNCTION__
);
keyspan_usa28_send_setup
(
port
->
serial
,
port
,
0
);
keyspan_usa28_send_setup
(
port
->
serial
,
port
,
p_priv
->
resend_cont
-
1
);
}
}
...
...
@@ -653,12 +663,12 @@ static void usa28_instat_callback(struct urb *urb)
/* wake_up_interruptible(&p_priv->open_wait); */
}
exit:
/* Resubmit urb so we continue receiving */
urb
->
dev
=
serial
->
dev
;
if
((
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
))
!=
0
)
{
dbg
(
"%s - resubmit read urb failed. (%d)"
,
__FUNCTION__
,
err
);
}
exit:
}
static
void
usa28_glocont_callback
(
struct
urb
*
urb
)
...
...
@@ -683,7 +693,7 @@ static void usa49_glocont_callback(struct urb *urb)
if
(
p_priv
->
resend_cont
)
{
dbg
(
"%s - sending setup"
,
__FUNCTION__
);
keyspan_usa49_send_setup
(
serial
,
port
,
0
);
keyspan_usa49_send_setup
(
serial
,
port
,
p_priv
->
resend_cont
-
1
);
break
;
}
}
...
...
@@ -745,13 +755,13 @@ static void usa49_instat_callback(struct urb *urb)
/* wake_up_interruptible(&p_priv->open_wait); */
}
exit:
/* Resubmit urb so we continue receiving */
urb
->
dev
=
serial
->
dev
;
if
((
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
))
!=
0
)
{
dbg
(
"%s - resubmit read urb failed. (%d)"
,
__FUNCTION__
,
err
);
}
exit:
}
static
void
usa49_inack_callback
(
struct
urb
*
urb
)
...
...
@@ -805,6 +815,7 @@ static void usa49_indat_callback(struct urb *urb)
/* Resubmit urb so we continue receiving */
urb
->
dev
=
port
->
serial
->
dev
;
if
(
port
->
open_count
)
if
((
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
))
!=
0
)
{
dbg
(
"%s - resubmit read urb failed. (%d)"
,
__FUNCTION__
,
err
);
}
...
...
@@ -820,9 +831,27 @@ static void usa49_outcont_callback(struct urb *urb)
static
int
keyspan_write_room
(
struct
usb_serial_port
*
port
)
{
struct
keyspan_port_private
*
p_priv
;
const
struct
keyspan_device_details
*
d_details
;
int
flip
;
struct
urb
*
this_urb
;
dbg
(
"%s"
,
__FUNCTION__
);
return
(
32
);
p_priv
=
(
struct
keyspan_port_private
*
)(
port
->
private
);
d_details
=
p_priv
->
device_details
;
flip
=
p_priv
->
out_flip
;
/* Check both endpoints to see if any are available. */
if
((
this_urb
=
p_priv
->
out_urbs
[
flip
])
!=
0
)
{
if
(
this_urb
->
status
!=
-
EINPROGRESS
)
return
(
63
);
flip
=
(
flip
+
1
)
&
d_details
->
outdat_endp_flip
;
if
((
this_urb
=
p_priv
->
out_urbs
[
flip
])
!=
0
)
if
(
this_urb
->
status
!=
-
EINPROGRESS
)
return
(
63
);
}
return
(
0
);
}
...
...
@@ -873,7 +902,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
if
((
urb
=
p_priv
->
out_urbs
[
i
])
==
NULL
)
continue
;
urb
->
dev
=
serial
->
dev
;
usb_settoggle
(
urb
->
dev
,
usb_pipeendpoint
(
urb
->
pipe
),
usb_pipeout
(
urb
->
pipe
),
0
);
/* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */
}
keyspan_send_setup
(
port
,
1
);
...
...
@@ -909,8 +938,12 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
p_priv
->
rts_state
=
0
;
p_priv
->
dtr_state
=
0
;
if
(
serial
->
dev
)
keyspan_send_setup
(
port
,
1
);
if
(
serial
->
dev
)
{
keyspan_send_setup
(
port
,
2
);
/* pilot-xfer seems to work best with this delay */
mdelay
(
100
);
keyspan_set_termios
(
port
,
NULL
);
}
/*while (p_priv->outcont_urb->status == -EINPROGRESS) {
dbg("%s - urb in progress", __FUNCTION__);
...
...
@@ -922,7 +955,7 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
if
(
serial
->
dev
)
{
/* Stop reading/writing urbs */
stop_urb
(
p_priv
->
inack_urb
);
stop_urb
(
p_priv
->
outcont_urb
);
/* stop_urb(p_priv->outcont_urb); */
for
(
i
=
0
;
i
<
2
;
i
++
)
{
stop_urb
(
p_priv
->
in_urbs
[
i
]);
stop_urb
(
p_priv
->
out_urbs
[
i
]);
...
...
@@ -1365,7 +1398,10 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
return
-
1
;
}
p_priv
->
resend_cont
=
1
;
/* Save reset port val for resend.
Don't overwrite resend for close condition. */
if
(
p_priv
->
resend_cont
!=
3
)
p_priv
->
resend_cont
=
reset_port
+
1
;
if
(
this_urb
->
status
==
-
EINPROGRESS
)
{
/* dbg ("%s - already writing", __FUNCTION__); */
return
(
-
1
);
...
...
@@ -1414,12 +1450,26 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
msg
.
ctsFlowControl
=
(
p_priv
->
flow_control
==
flow_cts
);
msg
.
xonFlowControl
=
0
;
msg
.
setFlowControl
=
0xff
;
msg
.
forwardingLength
=
1
;
msg
.
forwardingLength
=
16
;
msg
.
xonChar
=
17
;
msg
.
xoffChar
=
19
;
if
(
reset_port
)
{
/* Opening port */
if
(
reset_port
==
1
)
{
msg
.
_txOn
=
1
;
msg
.
_txOff
=
0
;
msg
.
txFlush
=
0
;
msg
.
txBreak
=
0
;
msg
.
rxOn
=
1
;
msg
.
rxOff
=
0
;
msg
.
rxFlush
=
1
;
msg
.
rxForward
=
0
;
msg
.
returnStatus
=
0
;
msg
.
resetDataToggle
=
0xff
;
}
/* Closing port */
else
if
(
reset_port
==
2
)
{
msg
.
_txOn
=
0
;
msg
.
_txOff
=
1
;
msg
.
txFlush
=
0
;
...
...
@@ -1429,14 +1479,16 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
msg
.
rxFlush
=
1
;
msg
.
rxForward
=
0
;
msg
.
returnStatus
=
0
;
msg
.
resetDataToggle
=
0
xff
;
msg
.
resetDataToggle
=
0
;
}
/* Sending intermediate configs */
else
{
msg
.
_txOn
=
(
!
p_priv
->
break_on
);
msg
.
_txOff
=
0
;
msg
.
txFlush
=
0
;
msg
.
txBreak
=
(
p_priv
->
break_on
);
msg
.
rxOn
=
1
;
msg
.
rxOn
=
0
;
msg
.
rxOff
=
0
;
msg
.
rxFlush
=
0
;
msg
.
rxForward
=
0
;
...
...
@@ -1496,7 +1548,10 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
return
-
1
;
}
p_priv
->
resend_cont
=
1
;
/* Save reset port val for resend.
Don't overwrite resend for close condition. */
if
(
p_priv
->
resend_cont
!=
3
)
p_priv
->
resend_cont
=
reset_port
+
1
;
if
(
this_urb
->
status
==
-
EINPROGRESS
)
{
dbg
(
"%s already writing"
,
__FUNCTION__
);
return
(
-
1
);
...
...
@@ -1522,7 +1577,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
msg
.
rts
=
p_priv
->
rts_state
;
msg
.
dtr
=
p_priv
->
dtr_state
;
msg
.
forwardingLength
=
1
;
msg
.
forwardingLength
=
1
6
;
msg
.
forwardMs
=
10
;
msg
.
breakThreshold
=
45
;
msg
.
xonChar
=
17
;
...
...
@@ -1530,8 +1585,22 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
/*msg.returnStatus = 1;
msg.resetDataToggle = 0xff;*/
if
(
reset_port
)
{
/* Opening port */
if
(
reset_port
==
1
)
{
msg
.
_txOn
=
1
;
msg
.
_txOff
=
0
;
msg
.
txFlush
=
0
;
msg
.
txForceXoff
=
0
;
msg
.
txBreak
=
0
;
msg
.
rxOn
=
1
;
msg
.
rxOff
=
0
;
msg
.
rxFlush
=
1
;
msg
.
rxForward
=
0
;
msg
.
returnStatus
=
0
;
msg
.
resetDataToggle
=
0xff
;
}
/* Closing port */
else
if
(
reset_port
==
2
)
{
msg
.
_txOn
=
0
;
msg
.
_txOff
=
1
;
msg
.
txFlush
=
0
;
...
...
@@ -1542,15 +1611,16 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
msg
.
rxFlush
=
1
;
msg
.
rxForward
=
0
;
msg
.
returnStatus
=
0
;
msg
.
resetDataToggle
=
0
xff
;
msg
.
resetDataToggle
=
0
;
}
/* Sending intermediate configs */
else
{
msg
.
_txOn
=
(
!
p_priv
->
break_on
);
msg
.
_txOff
=
0
;
msg
.
txFlush
=
0
;
msg
.
txForceXoff
=
0
;
msg
.
txBreak
=
(
p_priv
->
break_on
);
msg
.
rxOn
=
1
;
msg
.
rxOn
=
0
;
msg
.
rxOff
=
0
;
msg
.
rxFlush
=
0
;
msg
.
rxForward
=
0
;
...
...
@@ -1610,7 +1680,10 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
return
-
1
;
}
p_priv
->
resend_cont
=
1
;
/* Save reset port val for resend.
Don't overwrite resend for close condition. */
if
(
p_priv
->
resend_cont
!=
3
)
p_priv
->
resend_cont
=
reset_port
+
1
;
if
(
this_urb
->
status
==
-
EINPROGRESS
)
{
/* dbg ("%s - already writing", __FUNCTION__); */
return
(
-
1
);
...
...
@@ -1663,11 +1736,27 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
msg
.
xonFlowControl
=
0
;
msg
.
setFlowControl
=
0xff
;
msg
.
forwardingLength
=
1
;
msg
.
forwardingLength
=
1
6
;
msg
.
xonChar
=
17
;
msg
.
xoffChar
=
19
;
if
(
reset_port
)
{
/* Opening port */
if
(
reset_port
==
1
)
{
msg
.
_txOn
=
1
;
msg
.
_txOff
=
0
;
msg
.
txFlush
=
0
;
msg
.
txBreak
=
0
;
msg
.
rxOn
=
1
;
msg
.
rxOff
=
0
;
msg
.
rxFlush
=
1
;
msg
.
rxForward
=
0
;
msg
.
returnStatus
=
0
;
msg
.
resetDataToggle
=
0xff
;
msg
.
enablePort
=
1
;
msg
.
disablePort
=
0
;
}
/* Closing port */
else
if
(
reset_port
==
2
)
{
msg
.
_txOn
=
0
;
msg
.
_txOff
=
1
;
msg
.
txFlush
=
0
;
...
...
@@ -1677,23 +1766,23 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
msg
.
rxFlush
=
1
;
msg
.
rxForward
=
0
;
msg
.
returnStatus
=
0
;
msg
.
resetDataToggle
=
0
xff
;
msg
.
resetDataToggle
=
0
;
msg
.
enablePort
=
0
;
msg
.
disablePort
=
0xff
;
msg
.
disablePort
=
1
;
}
/* Sending intermediate configs */
else
{
msg
.
_txOn
=
(
!
p_priv
->
break_on
);
msg
.
_txOff
=
0
;
msg
.
txFlush
=
0
;
msg
.
txBreak
=
(
p_priv
->
break_on
);
msg
.
rxOn
=
1
;
msg
.
rxOn
=
0
;
msg
.
rxOff
=
0
;
msg
.
rxFlush
=
0
;
msg
.
rxForward
=
0
;
msg
.
returnStatus
=
0
;
msg
.
resetDataToggle
=
0x0
;
msg
.
enablePort
=
0
xff
;
msg
.
enablePort
=
0
;
msg
.
disablePort
=
0
;
}
...
...
drivers/usb/usb-skeleton.c
View file @
f0dbe47d
...
...
@@ -85,12 +85,20 @@ static struct usb_device_id skel_table [] = {
MODULE_DEVICE_TABLE
(
usb
,
skel_table
);
#ifdef CONFIG_USB_DYNAMIC_MINORS
/*
* if the user wants to use dynamic minor numbers, then we can have up to 256
* devices
*/
#define USB_SKEL_MINOR_BASE 0
#define MAX_DEVICES 256
#else
/* Get a minor range for your devices from the usb maintainer */
#define USB_SKEL_MINOR_BASE 200
/* we can have up to this number of device plugged in at once */
#define MAX_DEVICES 16
#endif
/* Structure to hold all of our device specific stuff */
struct
usb_skel
{
...
...
@@ -192,9 +200,6 @@ static struct usb_driver skel_driver = {
};
/**
* usb_skel_debug_data
*/
...
...
@@ -529,8 +534,9 @@ static void * skel_probe(struct usb_device *udev, unsigned int ifnum, const stru
return
NULL
;
}
/* select a "subminor" number (part of a minor number) */
down
(
&
minor_table_mutex
);
if
(
usb_register_dev
(
&
skel_driver
,
1
,
&
minor
))
{
/* we could not get a dynamic minor, so lets find one of our own */
for
(
minor
=
0
;
minor
<
MAX_DEVICES
;
++
minor
)
{
if
(
minor_table
[
minor
]
==
NULL
)
break
;
...
...
@@ -539,6 +545,7 @@ static void * skel_probe(struct usb_device *udev, unsigned int ifnum, const stru
info
(
"Too many devices plugged in, can not handle this device."
);
goto
exit
;
}
}
/* allocate memory for our device state and intialize it */
dev
=
kmalloc
(
sizeof
(
struct
usb_skel
),
GFP_KERNEL
);
...
...
@@ -642,7 +649,10 @@ static void skel_disconnect(struct usb_device *udev, void *ptr)
minor
=
dev
->
minor
;
/* remove our devfs node */
devfs_unregister
(
dev
->
devfs
);
devfs_unregister
(
dev
->
devfs
);
/* give back our dynamic minor */
usb_deregister_dev
(
&
skel_driver
,
1
,
minor
);
/* if the device is not opened, then we clean up right now */
if
(
!
dev
->
open_count
)
{
...
...
include/linux/brlvger.h
View file @
f0dbe47d
...
...
@@ -30,11 +30,16 @@
#define BRLVGER_DISPLAY_OFF 3
#define BRLVGER_BUZZ 4
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define MAX_NR_BRLVGER_DEVS 256
#define BRLVGER_MINOR 0
#else
/* Number of supported devices, and range of covered minors */
#define MAX_NR_BRLVGER_DEVS
2
#define MAX_NR_BRLVGER_DEVS
4
/* Base minor for the char devices */
#define BRLVGER_MINOR 128
#endif
/* Size of some fields */
#define BRLVGER_HWVER_SIZE 2
...
...
include/linux/usb.h
View file @
f0dbe47d
...
...
@@ -2,6 +2,7 @@
#define __LINUX_USB_H
#include <linux/device.h>
#include <linux/errno.h>
/* USB constants */
...
...
@@ -317,6 +318,223 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\
type,(void**)ptr)
/* -------------------------------------------------------------------------- */
/* Host Controller Driver (HCD) support */
struct
usb_operations
;
#define DEVNUM_ROUND_ROBIN
/***** OPTION *****/
/*
* Allocated per bus we have
*/
struct
usb_bus
{
int
busnum
;
/* Bus number (in order of reg) */
char
*
bus_name
;
/* stable id (PCI slot_name etc) */
#ifdef DEVNUM_ROUND_ROBIN
int
devnum_next
;
/* Next open device number in round-robin allocation */
#endif
/* DEVNUM_ROUND_ROBIN */
struct
usb_devmap
devmap
;
/* device address allocation map */
struct
usb_operations
*
op
;
/* Operations (specific to the HC) */
struct
usb_device
*
root_hub
;
/* Root hub */
struct
list_head
bus_list
;
/* list of busses */
void
*
hcpriv
;
/* Host Controller private data */
int
bandwidth_allocated
;
/* on this bus: how much of the time
* reserved for periodic (intr/iso)
* requests is used, on average?
* Units: microseconds/frame.
* Limits: Full/low speed reserve 90%,
* while high speed reserves 80%.
*/
int
bandwidth_int_reqs
;
/* number of Interrupt requests */
int
bandwidth_isoc_reqs
;
/* number of Isoc. requests */
struct
dentry
*
dentry
;
/* usbfs dentry entry for the bus */
atomic_t
refcnt
;
};
// FIXME: root_hub_string vanishes when "usb_hcd" conversion is done,
// along with pre-hcd versions of the OHCI and UHCI drivers.
extern
int
usb_root_hub_string
(
int
id
,
int
serial
,
char
*
type
,
__u8
*
data
,
int
len
);
/*
* As of USB 2.0, full/low speed devices are segregated into trees.
* One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
* The other type grows from high speed hubs when they connect to
* full/low speed devices using "Transaction Translators" (TTs).
*
* TTs should only be known to the hub driver, and high speed bus
* drivers (only EHCI for now). They affect periodic scheduling and
* sometimes control/bulk error recovery.
*/
struct
usb_tt
{
struct
usb_device
*
hub
;
/* upstream highspeed hub */
int
multi
;
/* true means one TT per port */
};
/* -------------------------------------------------------------------------- */
/* This is arbitrary.
* From USB 2.0 spec Table 11-13, offset 7, a hub can
* have up to 255 ports. The most yet reported is 10.
*/
#define USB_MAXCHILDREN (16)
struct
usb_device
{
int
devnum
;
/* Address on USB bus */
char
devpath
[
16
];
/* Use in messages: /port/port/... */
enum
{
USB_SPEED_UNKNOWN
=
0
,
/* enumerating */
USB_SPEED_LOW
,
USB_SPEED_FULL
,
/* usb 1.1 */
USB_SPEED_HIGH
/* usb 2.0 */
}
speed
;
struct
usb_tt
*
tt
;
/* low/full speed dev, highspeed hub */
int
ttport
;
/* device port on that tt hub */
atomic_t
refcnt
;
/* Reference count */
struct
semaphore
serialize
;
unsigned
int
toggle
[
2
];
/* one bit for each endpoint ([0] = IN, [1] = OUT) */
unsigned
int
halted
[
2
];
/* endpoint halts; one bit per endpoint # & direction; */
/* [0] = IN, [1] = OUT */
int
epmaxpacketin
[
16
];
/* INput endpoint specific maximums */
int
epmaxpacketout
[
16
];
/* OUTput endpoint specific maximums */
struct
usb_device
*
parent
;
/* our hub, unless we're the root */
struct
usb_bus
*
bus
;
/* Bus we're part of */
struct
device
dev
;
/* Generic device interface */
struct
usb_device_descriptor
descriptor
;
/* Descriptor */
struct
usb_config_descriptor
*
config
;
/* All of the configs */
struct
usb_config_descriptor
*
actconfig
;
/* the active configuration */
char
**
rawdescriptors
;
/* Raw descriptors for each config */
int
have_langid
;
/* whether string_langid is valid yet */
int
string_langid
;
/* language ID for strings */
void
*
hcpriv
;
/* Host Controller private data */
struct
list_head
filelist
;
struct
dentry
*
dentry
;
/* usbfs dentry entry for the device */
/*
* Child devices - these can be either new devices
* (if this is a hub device), or different instances
* of this same device.
*
* Each instance needs its own set of data structures.
*/
int
maxchild
;
/* Number of ports if hub */
struct
usb_device
*
children
[
USB_MAXCHILDREN
];
};
/* for when layers above USB add new non-USB drivers */
extern
void
usb_scan_devices
(
void
);
/* mostly for devices emulating SCSI over USB */
extern
int
usb_reset_device
(
struct
usb_device
*
dev
);
/* for drivers using iso endpoints */
extern
int
usb_get_current_frame_number
(
struct
usb_device
*
usb_dev
);
/**
* usb_inc_dev_use - record another reference to a device
* @dev: the device being referenced
*
* Each live reference to a device should be refcounted.
*
* Drivers for USB interfaces should normally record such references in
* their probe() methods, when they bind to an interface, and release
* them usb_dec_dev_use(), in their disconnect() methods.
*/
static
inline
void
usb_inc_dev_use
(
struct
usb_device
*
dev
)
{
atomic_inc
(
&
dev
->
refcnt
);
}
/**
* usb_dec_dev_use - drop a reference to a device
* @dev: the device no longer being referenced
*
* Each live reference to a device should be refcounted.
*
* Drivers for USB interfaces should normally release such references in
* their disconnect() methods, and record them in probe().
*
* Note that driver disconnect() methods must guarantee that when they
* return, all of their outstanding references to the device (and its
* interfaces) are cleaned up. That means that all pending URBs from
* this driver must have completed, and that no more copies of the device
* handle are saved in driver records (including other kernel threads).
*/
static
inline
void
usb_dec_dev_use
(
struct
usb_device
*
dev
)
{
if
(
atomic_dec_and_test
(
&
dev
->
refcnt
))
{
/* May only go to zero when usbcore finishes
* usb_disconnect() processing: khubd or HCDs.
*
* If you hit this BUG() it's likely a problem
* with some driver's disconnect() routine.
*/
BUG
();
}
}
/* used these for multi-interface device registration */
extern
int
usb_find_interface_driver_for_ifnum
(
struct
usb_device
*
dev
,
unsigned
int
ifnum
);
extern
void
usb_driver_claim_interface
(
struct
usb_driver
*
driver
,
struct
usb_interface
*
iface
,
void
*
priv
);
extern
int
usb_interface_claimed
(
struct
usb_interface
*
iface
);
extern
void
usb_driver_release_interface
(
struct
usb_driver
*
driver
,
struct
usb_interface
*
iface
);
const
struct
usb_device_id
*
usb_match_id
(
struct
usb_device
*
dev
,
struct
usb_interface
*
interface
,
const
struct
usb_device_id
*
id
);
/**
* usb_make_path - returns stable device path in the usb tree
* @dev: the device whose path is being constructed
* @buf: where to put the string
* @size: how big is "buf"?
*
* Returns length of the string (> 0) or negative if size was too small.
*
* This identifier is intended to be "stable", reflecting physical paths in
* hardware such as physical bus addresses for host controllers or ports on
* USB hubs. That makes it stay the same until systems are physically
* reconfigured, by re-cabling a tree of USB devices or by moving USB host
* controllers. Adding and removing devices, including virtual root hubs
* in host controller driver modules, does not change these path identifers;
* neither does rebooting or re-enumerating. These are more useful identifiers
* than changeable ("unstable") ones like bus numbers or device addresses.
*
* With a partial exception for devices connected to USB 2.0 root hubs, these
* identifiers are also predictable: so long as the device tree isn't changed,
* plugging any USB device into a given hub port always gives it the same path.
* Because of the use of "companion" controllers, devices connected to ports on
* USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are
* high speed, and a different one if they are full or low speed.
*/
static
inline
int
usb_make_path
(
struct
usb_device
*
dev
,
char
*
buf
,
size_t
size
)
{
int
actual
;
actual
=
snprintf
(
buf
,
size
,
"usb-%s-%s"
,
dev
->
bus
->
bus_name
,
dev
->
devpath
);
return
(
actual
>=
size
)
?
-
1
:
actual
;
}
/*-------------------------------------------------------------------------*/
/*
...
...
@@ -559,6 +777,14 @@ struct usb_driver {
extern
int
usb_register
(
struct
usb_driver
*
);
extern
void
usb_deregister
(
struct
usb_driver
*
);
#ifndef CONFIG_USB_DYNAMIC_MINORS
static
inline
int
usb_register_dev
(
struct
usb_driver
*
new_driver
,
int
num_minors
,
int
*
start_minor
)
{
return
-
ENODEV
;
}
static
inline
void
usb_deregister_dev
(
struct
usb_driver
*
driver
,
int
num_minors
,
int
start_minor
)
{}
#else
extern
int
usb_register_dev
(
struct
usb_driver
*
new_driver
,
int
num_minors
,
int
*
start_minor
);
extern
void
usb_deregister_dev
(
struct
usb_driver
*
driver
,
int
num_minors
,
int
start_minor
);
#endif
/* -------------------------------------------------------------------------- */
/*
...
...
@@ -826,10 +1052,14 @@ static inline void usb_fill_bulk_urb (struct urb *urb,
* @buffer_length: length of the transfer buffer
* @complete: pointer to the usb_complete_t function
* @context: what to set the urb context to.
* @interval: what to set the urb interval to.
* @interval: what to set the urb interval to, encoded like
* the endpoint descriptor's bInterval value.
*
* Initializes a interrupt urb with the proper information needed to submit
* it to a device.
* Note that high speed interrupt endpoints use a logarithmic encoding of
* the endpoint interval, and express polling intervals in microframes
* (eight per millisecond) rather than in frames (one per millisecond).
*/
static
inline
void
usb_fill_int_urb
(
struct
urb
*
urb
,
struct
usb_device
*
dev
,
...
...
@@ -847,6 +1077,9 @@ static inline void usb_fill_int_urb (struct urb *urb,
urb
->
transfer_buffer_length
=
buffer_length
;
urb
->
complete
=
complete
;
urb
->
context
=
context
;
if
(
dev
->
speed
==
USB_SPEED_HIGH
)
urb
->
interval
=
1
<<
(
interval
-
1
);
else
urb
->
interval
=
interval
;
urb
->
start_frame
=
-
1
;
}
...
...
@@ -908,221 +1141,6 @@ extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
/* -------------------------------------------------------------------------- */
/* Host Controller Driver (HCD) support */
struct
usb_operations
;
#define DEVNUM_ROUND_ROBIN
/***** OPTION *****/
/*
* Allocated per bus we have
*/
struct
usb_bus
{
int
busnum
;
/* Bus number (in order of reg) */
char
*
bus_name
;
/* stable id (PCI slot_name etc) */
#ifdef DEVNUM_ROUND_ROBIN
int
devnum_next
;
/* Next open device number in round-robin allocation */
#endif
/* DEVNUM_ROUND_ROBIN */
struct
usb_devmap
devmap
;
/* Device map */
struct
usb_operations
*
op
;
/* Operations (specific to the HC) */
struct
usb_device
*
root_hub
;
/* Root hub */
struct
list_head
bus_list
;
void
*
hcpriv
;
/* Host Controller private data */
int
bandwidth_allocated
;
/* on this Host Controller; */
/* applies to Int. and Isoc. pipes; */
/* measured in microseconds/frame; */
/* range is 0..900, where 900 = */
/* 90% of a 1-millisecond frame */
int
bandwidth_int_reqs
;
/* number of Interrupt requesters */
int
bandwidth_isoc_reqs
;
/* number of Isoc. requesters */
struct
dentry
*
dentry
;
/* usbfs dentry entry for the bus */
atomic_t
refcnt
;
};
// FIXME: root_hub_string vanishes when "usb_hcd" conversion is done,
// along with pre-hcd versions of the OHCI and UHCI drivers.
extern
int
usb_root_hub_string
(
int
id
,
int
serial
,
char
*
type
,
__u8
*
data
,
int
len
);
/*
* As of USB 2.0, full/low speed devices are segregated into trees.
* One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
* The other type grows from high speed hubs when they connect to
* full/low speed devices using "Transaction Translators" (TTs).
*
* TTs should only be known to the hub driver, and high speed bus
* drivers (only EHCI for now). They affect periodic scheduling and
* sometimes control/bulk error recovery.
*/
struct
usb_tt
{
struct
usb_device
*
hub
;
/* upstream highspeed hub */
int
multi
;
/* true means one TT per port */
};
/* -------------------------------------------------------------------------- */
/* This is arbitrary.
* From USB 2.0 spec Table 11-13, offset 7, a hub can
* have up to 255 ports. The most yet reported is 10.
*/
#define USB_MAXCHILDREN (16)
struct
usb_device
{
int
devnum
;
/* Address on USB bus */
char
devpath
[
16
];
/* Use in messages: /port/port/... */
enum
{
USB_SPEED_UNKNOWN
=
0
,
/* enumerating */
USB_SPEED_LOW
,
USB_SPEED_FULL
,
/* usb 1.1 */
USB_SPEED_HIGH
/* usb 2.0 */
}
speed
;
struct
usb_tt
*
tt
;
/* low/full speed dev, highspeed hub */
int
ttport
;
/* device port on that tt hub */
atomic_t
refcnt
;
/* Reference count */
struct
semaphore
serialize
;
unsigned
int
toggle
[
2
];
/* one bit for each endpoint ([0] = IN, [1] = OUT) */
unsigned
int
halted
[
2
];
/* endpoint halts; one bit per endpoint # & direction; */
/* [0] = IN, [1] = OUT */
int
epmaxpacketin
[
16
];
/* INput endpoint specific maximums */
int
epmaxpacketout
[
16
];
/* OUTput endpoint specific maximums */
struct
usb_device
*
parent
;
struct
usb_bus
*
bus
;
/* Bus we're part of */
struct
device
dev
;
/* Generic device interface */
struct
usb_device_descriptor
descriptor
;
/* Descriptor */
struct
usb_config_descriptor
*
config
;
/* All of the configs */
struct
usb_config_descriptor
*
actconfig
;
/* the active configuration */
char
**
rawdescriptors
;
/* Raw descriptors for each config */
int
have_langid
;
/* whether string_langid is valid yet */
int
string_langid
;
/* language ID for strings */
void
*
hcpriv
;
/* Host Controller private data */
struct
list_head
filelist
;
struct
dentry
*
dentry
;
/* usbfs dentry entry for the device */
/*
* Child devices - these can be either new devices
* (if this is a hub device), or different instances
* of this same device.
*
* Each instance needs its own set of data structures.
*/
int
maxchild
;
/* Number of ports if hub */
struct
usb_device
*
children
[
USB_MAXCHILDREN
];
};
/* for when layers above USB add new non-USB drivers */
extern
void
usb_scan_devices
(
void
);
/* mostly for devices emulating SCSI over USB */
extern
int
usb_reset_device
(
struct
usb_device
*
dev
);
/* for drivers using iso endpoints */
extern
int
usb_get_current_frame_number
(
struct
usb_device
*
usb_dev
);
/**
* usb_inc_dev_use - record another reference to a device
* @dev: the device being referenced
*
* Each live reference to a device should be refcounted.
*
* Drivers for USB interfaces should normally record such references in
* their probe() methods, when they bind to an interface, and release
* them usb_dec_dev_use(), in their disconnect() methods.
*/
static
inline
void
usb_inc_dev_use
(
struct
usb_device
*
dev
)
{
atomic_inc
(
&
dev
->
refcnt
);
}
/**
* usb_dec_dev_use - drop a reference to a device
* @dev: the device no longer being referenced
*
* Each live reference to a device should be refcounted.
*
* Drivers for USB interfaces should normally release such references in
* their disconnect() methods, and record them in probe().
*
* Note that driver disconnect() methods must guarantee that when they
* return, all of their outstanding references to the device (and its
* interfaces) are cleaned up. That means that all pending URBs from
* this driver must have completed, and that no more copies of the device
* handle are saved in driver records (including other kernel threads).
*/
static
inline
void
usb_dec_dev_use
(
struct
usb_device
*
dev
)
{
if
(
atomic_dec_and_test
(
&
dev
->
refcnt
))
{
/* May only go to zero when usbcore finishes
* usb_disconnect() processing: khubd or HCDs.
*
* If you hit this BUG() it's likely a problem
* with some driver's disconnect() routine.
*/
BUG
();
}
}
/* used these for multi-interface device registration */
extern
int
usb_find_interface_driver_for_ifnum
(
struct
usb_device
*
dev
,
unsigned
int
ifnum
);
extern
void
usb_driver_claim_interface
(
struct
usb_driver
*
driver
,
struct
usb_interface
*
iface
,
void
*
priv
);
extern
int
usb_interface_claimed
(
struct
usb_interface
*
iface
);
extern
void
usb_driver_release_interface
(
struct
usb_driver
*
driver
,
struct
usb_interface
*
iface
);
const
struct
usb_device_id
*
usb_match_id
(
struct
usb_device
*
dev
,
struct
usb_interface
*
interface
,
const
struct
usb_device_id
*
id
);
/**
* usb_make_path - returns stable device path in the usb tree
* @dev: the device whose path is being constructed
* @buf: where to put the string
* @size: how big is "buf"?
*
* Returns length of the string (> 0) or negative if size was too small.
*
* This identifier is intended to be "stable", reflecting physical paths in
* hardware such as physical bus addresses for host controllers or ports on
* USB hubs. That makes it stay the same until systems are physically
* reconfigured, by re-cabling a tree of USB devices or by moving USB host
* controllers. Adding and removing devices, including virtual root hubs
* in host controller driver modules, does not change these path identifers;
* neither does rebooting or re-enumerating. These are more useful identifiers
* than changeable ("unstable") ones like bus numbers or device addresses.
*
* With a partial exception for devices connected to USB 2.0 root hubs, these
* identifiers are also predictable: so long as the device tree isn't changed,
* plugging any USB device into a given hub port always gives it the same path.
* Because of the use of "companion" controllers, devices connected to ports on
* USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are
* high speed, and a different one if they are full or low speed.
*/
static
inline
int
usb_make_path
(
struct
usb_device
*
dev
,
char
*
buf
,
size_t
size
)
{
int
actual
;
actual
=
snprintf
(
buf
,
size
,
"usb-%s-%s"
,
dev
->
bus
->
bus_name
,
dev
->
devpath
);
return
(
actual
>=
size
)
?
-
1
:
actual
;
}
/* -------------------------------------------------------------------------- */
/*
* Calling this entity a "pipe" is glorifying it. A USB pipe
* is something embarrassingly simple: it basically consists
...
...
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