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
e9b73ef9
Commit
e9b73ef9
authored
May 28, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/gregkh/linux/usb-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
3bf8a198
075769bc
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
670 additions
and
488 deletions
+670
-488
drivers/usb/class/usblp.c
drivers/usb/class/usblp.c
+17
-4
drivers/usb/core/Makefile
drivers/usb/core/Makefile
+1
-1
drivers/usb/core/config.c
drivers/usb/core/config.c
+9
-8
drivers/usb/core/hcd.h
drivers/usb/core/hcd.h
+2
-2
drivers/usb/core/hub.c
drivers/usb/core/hub.c
+300
-286
drivers/usb/core/message.c
drivers/usb/core/message.c
+1
-1
drivers/usb/core/sysfs.c
drivers/usb/core/sysfs.c
+4
-4
drivers/usb/core/usb.c
drivers/usb/core/usb.c
+54
-53
drivers/usb/core/usb.h
drivers/usb/core/usb.h
+2
-2
drivers/usb/gadget/Kconfig
drivers/usb/gadget/Kconfig
+1
-0
drivers/usb/gadget/epautoconf.c
drivers/usb/gadget/epautoconf.c
+2
-1
drivers/usb/gadget/serial.c
drivers/usb/gadget/serial.c
+3
-6
drivers/usb/host/uhci-hcd.c
drivers/usb/host/uhci-hcd.c
+46
-5
drivers/usb/host/uhci-hcd.h
drivers/usb/host/uhci-hcd.h
+3
-0
drivers/usb/input/hiddev.c
drivers/usb/input/hiddev.c
+1
-1
drivers/usb/input/powermate.c
drivers/usb/input/powermate.c
+12
-8
drivers/usb/net/kaweth.c
drivers/usb/net/kaweth.c
+5
-4
drivers/usb/net/pegasus.h
drivers/usb/net/pegasus.h
+3
-0
drivers/usb/serial/Kconfig
drivers/usb/serial/Kconfig
+2
-2
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.c
+103
-22
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/kobil_sct.c
+33
-16
drivers/usb/serial/visor.c
drivers/usb/serial/visor.c
+65
-60
drivers/usb/storage/transport.c
drivers/usb/storage/transport.c
+1
-2
No files found.
drivers/usb/class/usblp.c
View file @
e9b73ef9
...
...
@@ -226,11 +226,21 @@ extern struct usb_driver usblp_driver;
static
int
usblp_ctrl_msg
(
struct
usblp
*
usblp
,
int
request
,
int
type
,
int
dir
,
int
recip
,
int
value
,
void
*
buf
,
int
len
)
{
int
retval
=
usb_control_msg
(
usblp
->
dev
,
int
retval
;
int
index
=
usblp
->
ifnum
;
/* High byte has the interface index.
Low byte has the alternate setting.
*/
if
((
request
==
USBLP_REQ_GET_ID
)
&&
(
type
==
USB_TYPE_CLASS
))
{
index
=
(
usblp
->
ifnum
<<
8
)
|
usblp
->
protocol
[
usblp
->
current_protocol
].
alt_setting
;
}
retval
=
usb_control_msg
(
usblp
->
dev
,
dir
?
usb_rcvctrlpipe
(
usblp
->
dev
,
0
)
:
usb_sndctrlpipe
(
usblp
->
dev
,
0
),
request
,
type
|
dir
|
recip
,
value
,
usblp
->
ifnum
,
buf
,
len
,
USBLP_WRITE_TIMEOUT
);
dbg
(
"usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d len: %#x result: %d"
,
request
,
!!
dir
,
recip
,
value
,
len
,
retval
);
request
,
type
|
dir
|
recip
,
value
,
index
,
buf
,
len
,
USBLP_WRITE_TIMEOUT
);
dbg
(
"usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d
idx: %d
len: %#x result: %d"
,
request
,
!!
dir
,
recip
,
value
,
index
,
len
,
retval
);
return
retval
<
0
?
retval
:
0
;
}
...
...
@@ -440,6 +450,9 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
goto
done
;
}
dbg
(
"usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)"
,
cmd
,
_IOC_TYPE
(
cmd
),
_IOC_NR
(
cmd
),
_IOC_SIZE
(
cmd
),
_IOC_DIR
(
cmd
)
);
if
(
_IOC_TYPE
(
cmd
)
==
'P'
)
/* new-style ioctl number */
switch
(
_IOC_NR
(
cmd
))
{
...
...
drivers/usb/core/Makefile
View file @
e9b73ef9
...
...
@@ -3,7 +3,7 @@
#
usbcore-objs
:=
usb.o hub.o hcd.o urb.o message.o
\
config.o file.o buffer.o
driver
fs.o
config.o file.o buffer.o
sys
fs.o
ifeq
($(CONFIG_PCI),y)
usbcore-objs
+=
hcd-pci.o
...
...
drivers/usb/core/config.c
View file @
e9b73ef9
...
...
@@ -465,23 +465,24 @@ int usb_get_configuration(struct usb_device *dev)
goto
err2
;
memset
(
dev
->
rawdescriptors
,
0
,
length
);
buffer
=
kmalloc
(
8
,
GFP_KERNEL
);
buffer
=
kmalloc
(
USB_DT_CONFIG_SIZE
,
GFP_KERNEL
);
if
(
!
buffer
)
goto
err2
;
desc
=
(
struct
usb_config_descriptor
*
)
buffer
;
for
(
cfgno
=
0
;
cfgno
<
ncfg
;
cfgno
++
)
{
/* We grab
the first 8 bytes so we know how long the whole */
/*
configuration is */
/* We grab
just the first descriptor so we know how long
* the whole
configuration is */
result
=
usb_get_descriptor
(
dev
,
USB_DT_CONFIG
,
cfgno
,
buffer
,
8
);
buffer
,
USB_DT_CONFIG_SIZE
);
if
(
result
<
0
)
{
dev_err
(
ddev
,
"unable to read config index %d "
"descriptor
\n
"
,
cfgno
);
"descriptor
/%s
\n
"
,
cfgno
,
"start"
);
goto
err
;
}
else
if
(
result
<
8
)
{
}
else
if
(
result
<
4
)
{
dev_err
(
ddev
,
"config index %d descriptor too short "
"(expected %i, got %i)
\n
"
,
cfgno
,
8
,
result
);
"(expected %i, got %i)
\n
"
,
cfgno
,
USB_DT_CONFIG_SIZE
,
result
);
result
=
-
EINVAL
;
goto
err
;
}
...
...
@@ -498,7 +499,7 @@ int usb_get_configuration(struct usb_device *dev)
bigbuffer
,
length
);
if
(
result
<
0
)
{
dev_err
(
ddev
,
"unable to read config index %d "
"descriptor
\n
"
,
cfgno
);
"descriptor
/%s
\n
"
,
cfgno
,
"all"
);
kfree
(
bigbuffer
);
goto
err
;
}
...
...
drivers/usb/core/hcd.h
View file @
e9b73ef9
...
...
@@ -243,13 +243,13 @@ extern void usb_hc_died (struct usb_hcd *hcd);
extern
struct
usb_device
*
usb_alloc_dev
(
struct
usb_device
*
parent
,
struct
usb_bus
*
,
unsigned
port
);
extern
int
usb_new_device
(
struct
usb_device
*
dev
);
extern
void
usb_choose_address
(
struct
usb_device
*
dev
);
extern
void
usb_disconnect
(
struct
usb_device
**
);
extern
void
usb_choose_address
(
struct
usb_device
*
dev
);
extern
void
usb_release_address
(
struct
usb_device
*
dev
);
/* exported to hub driver ONLY to support usb_reset_device () */
extern
int
usb_get_configuration
(
struct
usb_device
*
dev
);
extern
void
usb_destroy_configuration
(
struct
usb_device
*
dev
);
extern
int
usb_set_address
(
struct
usb_device
*
dev
);
/* use these only before the device's address has been set */
#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30))
...
...
drivers/usb/core/hub.c
View file @
e9b73ef9
...
...
@@ -65,15 +65,15 @@ static inline char *portspeed (int portstatus)
#endif
/* for dev_info, dev_dbg, etc */
static
inline
struct
device
*
hubdev
(
struct
usb_device
*
dev
)
static
inline
struct
device
*
hubdev
(
struct
usb_device
*
h
dev
)
{
return
&
dev
->
actconfig
->
interface
[
0
]
->
dev
;
return
&
h
dev
->
actconfig
->
interface
[
0
]
->
dev
;
}
/* USB 2.0 spec Section 11.24.4.5 */
static
int
get_hub_descriptor
(
struct
usb_device
*
dev
,
void
*
data
,
int
size
)
static
int
get_hub_descriptor
(
struct
usb_device
*
h
dev
,
void
*
data
,
int
size
)
{
return
usb_control_msg
(
dev
,
usb_rcvctrlpipe
(
dev
,
0
),
return
usb_control_msg
(
hdev
,
usb_rcvctrlpipe
(
h
dev
,
0
),
USB_REQ_GET_DESCRIPTOR
,
USB_DIR_IN
|
USB_RT_HUB
,
USB_DT_HUB
<<
8
,
0
,
data
,
size
,
HZ
*
USB_CTRL_GET_TIMEOUT
);
}
...
...
@@ -81,27 +81,27 @@ static int get_hub_descriptor(struct usb_device *dev, void *data, int size)
/*
* USB 2.0 spec Section 11.24.2.1
*/
static
int
clear_hub_feature
(
struct
usb_device
*
dev
,
int
feature
)
static
int
clear_hub_feature
(
struct
usb_device
*
h
dev
,
int
feature
)
{
return
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
return
usb_control_msg
(
hdev
,
usb_sndctrlpipe
(
h
dev
,
0
),
USB_REQ_CLEAR_FEATURE
,
USB_RT_HUB
,
feature
,
0
,
NULL
,
0
,
HZ
);
}
/*
* USB 2.0 spec Section 11.24.2.2
*/
static
int
clear_port_feature
(
struct
usb_device
*
dev
,
int
port
,
int
feature
)
static
int
clear_port_feature
(
struct
usb_device
*
h
dev
,
int
port
,
int
feature
)
{
return
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
return
usb_control_msg
(
hdev
,
usb_sndctrlpipe
(
h
dev
,
0
),
USB_REQ_CLEAR_FEATURE
,
USB_RT_PORT
,
feature
,
port
,
NULL
,
0
,
HZ
);
}
/*
* USB 2.0 spec Section 11.24.2.13
*/
static
int
set_port_feature
(
struct
usb_device
*
dev
,
int
port
,
int
feature
)
static
int
set_port_feature
(
struct
usb_device
*
h
dev
,
int
port
,
int
feature
)
{
return
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
return
usb_control_msg
(
hdev
,
usb_sndctrlpipe
(
h
dev
,
0
),
USB_REQ_SET_FEATURE
,
USB_RT_PORT
,
feature
,
port
,
NULL
,
0
,
HZ
);
}
...
...
@@ -110,16 +110,15 @@ static int set_port_feature(struct usb_device *dev, int port, int feature)
* for info about using port indicators
*/
static
void
set_port_led
(
struct
usb_device
*
dev
,
struct
usb_hub
*
hub
,
struct
usb_device
*
hdev
,
int
port
,
int
selector
)
{
int
status
=
set_port_feature
(
dev
,
(
selector
<<
8
)
|
port
,
int
status
=
set_port_feature
(
h
dev
,
(
selector
<<
8
)
|
port
,
USB_PORT_FEAT_INDICATOR
);
if
(
status
<
0
)
dev_dbg
(
&
hub
->
intf
->
dev
,
dev_dbg
(
hubdev
(
hdev
)
,
"port %d indicator %s status %d
\n
"
,
port
,
({
char
*
s
;
switch
(
selector
)
{
...
...
@@ -137,12 +136,12 @@ static void set_port_led(
static
void
led_work
(
void
*
__hub
)
{
struct
usb_hub
*
hub
=
__hub
;
struct
usb_device
*
dev
=
interface_to_usbdev
(
hub
->
intf
);
struct
usb_device
*
h
dev
=
interface_to_usbdev
(
hub
->
intf
);
unsigned
i
;
unsigned
changed
=
0
;
int
cursor
=
-
1
;
if
(
dev
->
state
!=
USB_STATE_CONFIGURED
)
if
(
h
dev
->
state
!=
USB_STATE_CONFIGURED
)
return
;
for
(
i
=
0
;
i
<
hub
->
descriptor
->
bNbrPorts
;
i
++
)
{
...
...
@@ -189,13 +188,13 @@ static void led_work (void *__hub)
}
if
(
selector
!=
HUB_LED_AUTO
)
changed
=
1
;
set_port_led
(
dev
,
hub
,
i
+
1
,
selector
);
set_port_led
(
hdev
,
i
+
1
,
selector
);
hub
->
indicator
[
i
]
=
mode
;
}
if
(
!
changed
&&
blinkenlights
)
{
cursor
++
;
cursor
%=
hub
->
descriptor
->
bNbrPorts
;
set_port_led
(
dev
,
hub
,
cursor
+
1
,
HUB_LED_GREEN
);
set_port_led
(
hdev
,
cursor
+
1
,
HUB_LED_GREEN
);
hub
->
indicator
[
cursor
]
=
INDICATOR_CYCLE
;
changed
++
;
}
...
...
@@ -206,10 +205,10 @@ static void led_work (void *__hub)
/*
* USB 2.0 spec Section 11.24.2.6
*/
static
int
get_hub_status
(
struct
usb_device
*
dev
,
static
int
get_hub_status
(
struct
usb_device
*
h
dev
,
struct
usb_hub_status
*
data
)
{
return
usb_control_msg
(
dev
,
usb_rcvctrlpipe
(
dev
,
0
),
return
usb_control_msg
(
hdev
,
usb_rcvctrlpipe
(
h
dev
,
0
),
USB_REQ_GET_STATUS
,
USB_DIR_IN
|
USB_RT_HUB
,
0
,
0
,
data
,
sizeof
(
*
data
),
HZ
*
USB_CTRL_GET_TIMEOUT
);
}
...
...
@@ -217,10 +216,10 @@ static int get_hub_status(struct usb_device *dev,
/*
* USB 2.0 spec Section 11.24.2.7
*/
static
int
get_port_status
(
struct
usb_device
*
dev
,
int
port
,
static
int
get_port_status
(
struct
usb_device
*
h
dev
,
int
port
,
struct
usb_port_status
*
data
)
{
return
usb_control_msg
(
dev
,
usb_rcvctrlpipe
(
dev
,
0
),
return
usb_control_msg
(
hdev
,
usb_rcvctrlpipe
(
h
dev
,
0
),
USB_REQ_GET_STATUS
,
USB_DIR_IN
|
USB_RT_PORT
,
0
,
port
,
data
,
sizeof
(
*
data
),
HZ
*
USB_CTRL_GET_TIMEOUT
);
}
...
...
@@ -278,9 +277,9 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs)
/* USB 2.0 spec Section 11.24.2.3 */
static
inline
int
hub_clear_tt_buffer
(
struct
usb_device
*
h
ub
,
u16
devinfo
,
u16
tt
)
hub_clear_tt_buffer
(
struct
usb_device
*
h
dev
,
u16
devinfo
,
u16
tt
)
{
return
usb_control_msg
(
h
ub
,
usb_rcvctrlpipe
(
hub
,
0
),
return
usb_control_msg
(
h
dev
,
usb_rcvctrlpipe
(
hdev
,
0
),
HUB_CLEAR_TT_BUFFER
,
USB_RT_PORT
,
devinfo
,
tt
,
0
,
0
,
HZ
);
}
...
...
@@ -300,7 +299,7 @@ static void hub_tt_kevent (void *arg)
while
(
!
list_empty
(
&
hub
->
tt
.
clear_list
))
{
struct
list_head
*
temp
;
struct
usb_tt_clear
*
clear
;
struct
usb_device
*
dev
;
struct
usb_device
*
h
dev
;
int
status
;
temp
=
hub
->
tt
.
clear_list
.
next
;
...
...
@@ -309,12 +308,13 @@ static void hub_tt_kevent (void *arg)
/* drop lock so HCD can concurrently report other TT errors */
spin_unlock_irqrestore
(
&
hub
->
tt
.
lock
,
flags
);
dev
=
interface_to_usbdev
(
hub
->
intf
);
status
=
hub_clear_tt_buffer
(
dev
,
clear
->
devinfo
,
clear
->
tt
);
h
dev
=
interface_to_usbdev
(
hub
->
intf
);
status
=
hub_clear_tt_buffer
(
h
dev
,
clear
->
devinfo
,
clear
->
tt
);
spin_lock_irqsave
(
&
hub
->
tt
.
lock
,
flags
);
if
(
status
)
dev_err
(
&
dev
->
dev
,
"clear tt %d (%04x) error %d
\n
"
,
dev_err
(
&
hdev
->
dev
,
"clear tt %d (%04x) error %d
\n
"
,
clear
->
tt
,
clear
->
devinfo
,
status
);
kfree
(
clear
);
}
...
...
@@ -334,9 +334,9 @@ static void hub_tt_kevent (void *arg)
* It may not be possible for that hub to handle additional full (or low)
* speed transactions until that state is fully cleared out.
*/
void
usb_hub_tt_clear_buffer
(
struct
usb_device
*
dev
,
int
pipe
)
void
usb_hub_tt_clear_buffer
(
struct
usb_device
*
u
dev
,
int
pipe
)
{
struct
usb_tt
*
tt
=
dev
->
tt
;
struct
usb_tt
*
tt
=
u
dev
->
tt
;
unsigned
long
flags
;
struct
usb_tt_clear
*
clear
;
...
...
@@ -345,15 +345,15 @@ void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe)
* there can be many TTs per hub). even if they're uncommon.
*/
if
((
clear
=
kmalloc
(
sizeof
*
clear
,
SLAB_ATOMIC
))
==
0
)
{
dev_err
(
&
dev
->
dev
,
"can't save CLEAR_TT_BUFFER state
\n
"
);
dev_err
(
&
u
dev
->
dev
,
"can't save CLEAR_TT_BUFFER state
\n
"
);
/* FIXME recover somehow ... RESET_TT? */
return
;
}
/* info that CLEAR_TT_BUFFER needs */
clear
->
tt
=
tt
->
multi
?
dev
->
ttport
:
1
;
clear
->
tt
=
tt
->
multi
?
u
dev
->
ttport
:
1
;
clear
->
devinfo
=
usb_pipeendpoint
(
pipe
);
clear
->
devinfo
|=
dev
->
devnum
<<
4
;
clear
->
devinfo
|=
u
dev
->
devnum
<<
4
;
clear
->
devinfo
|=
usb_pipecontrol
(
pipe
)
?
(
USB_ENDPOINT_XFER_CONTROL
<<
11
)
:
(
USB_ENDPOINT_XFER_BULK
<<
11
);
...
...
@@ -369,15 +369,15 @@ void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe)
static
void
hub_power_on
(
struct
usb_hub
*
hub
)
{
struct
usb_device
*
dev
;
struct
usb_device
*
h
dev
;
int
i
;
/* if hub supports power switching, enable power on each port */
if
((
hub
->
descriptor
->
wHubCharacteristics
&
HUB_CHAR_LPSM
)
<
2
)
{
dev_dbg
(
&
hub
->
intf
->
dev
,
"enabling power on all ports
\n
"
);
dev
=
interface_to_usbdev
(
hub
->
intf
);
h
dev
=
interface_to_usbdev
(
hub
->
intf
);
for
(
i
=
0
;
i
<
hub
->
descriptor
->
bNbrPorts
;
i
++
)
set_port_feature
(
dev
,
i
+
1
,
USB_PORT_FEAT_POWER
);
set_port_feature
(
h
dev
,
i
+
1
,
USB_PORT_FEAT_POWER
);
}
/* Wait for power to be enabled */
...
...
@@ -387,12 +387,12 @@ static void hub_power_on(struct usb_hub *hub)
static
int
hub_hub_status
(
struct
usb_hub
*
hub
,
u16
*
status
,
u16
*
change
)
{
struct
usb_device
*
dev
=
interface_to_usbdev
(
hub
->
intf
);
struct
usb_device
*
h
dev
=
interface_to_usbdev
(
hub
->
intf
);
int
ret
;
ret
=
get_hub_status
(
dev
,
&
hub
->
status
->
hub
);
ret
=
get_hub_status
(
h
dev
,
&
hub
->
status
->
hub
);
if
(
ret
<
0
)
dev_err
(
hubdev
(
dev
)
,
dev_err
(
&
hub
->
intf
->
dev
,
"%s failed (err = %d)
\n
"
,
__FUNCTION__
,
ret
);
else
{
*
status
=
le16_to_cpu
(
hub
->
status
->
hub
.
wHubStatus
);
...
...
@@ -405,14 +405,14 @@ static int hub_hub_status(struct usb_hub *hub,
static
int
hub_configure
(
struct
usb_hub
*
hub
,
struct
usb_endpoint_descriptor
*
endpoint
)
{
struct
usb_device
*
dev
=
interface_to_usbdev
(
hub
->
intf
);
struct
device
*
hub_dev
;
struct
usb_device
*
h
dev
=
interface_to_usbdev
(
hub
->
intf
);
struct
device
*
hub_dev
=
&
hub
->
intf
->
dev
;
u16
hubstatus
,
hubchange
;
unsigned
int
pipe
;
int
maxp
,
ret
;
char
*
message
;
hub
->
buffer
=
usb_buffer_alloc
(
dev
,
sizeof
(
*
hub
->
buffer
),
GFP_KERNEL
,
hub
->
buffer
=
usb_buffer_alloc
(
h
dev
,
sizeof
(
*
hub
->
buffer
),
GFP_KERNEL
,
&
hub
->
buffer_dma
);
if
(
!
hub
->
buffer
)
{
message
=
"can't allocate hub irq buffer"
;
...
...
@@ -438,7 +438,7 @@ static int hub_configure(struct usb_hub *hub,
* hub->descriptor can handle USB_MAXCHILDREN ports,
* but the hub can/will return fewer bytes here.
*/
ret
=
get_hub_descriptor
(
dev
,
hub
->
descriptor
,
ret
=
get_hub_descriptor
(
h
dev
,
hub
->
descriptor
,
sizeof
(
*
hub
->
descriptor
));
if
(
ret
<
0
)
{
message
=
"can't read hub descriptor"
;
...
...
@@ -449,10 +449,9 @@ static int hub_configure(struct usb_hub *hub,
goto
fail
;
}
hub_dev
=
hubdev
(
dev
);
dev
->
maxchild
=
hub
->
descriptor
->
bNbrPorts
;
dev_info
(
hub_dev
,
"%d port%s detected
\n
"
,
dev
->
maxchild
,
(
dev
->
maxchild
==
1
)
?
""
:
"s"
);
hdev
->
maxchild
=
hub
->
descriptor
->
bNbrPorts
;
dev_info
(
hub_dev
,
"%d port%s detected
\n
"
,
hdev
->
maxchild
,
(
hdev
->
maxchild
==
1
)
?
""
:
"s"
);
le16_to_cpus
(
&
hub
->
descriptor
->
wHubCharacteristics
);
...
...
@@ -460,11 +459,11 @@ static int hub_configure(struct usb_hub *hub,
int
i
;
char
portstr
[
USB_MAXCHILDREN
+
1
];
for
(
i
=
0
;
i
<
dev
->
maxchild
;
i
++
)
for
(
i
=
0
;
i
<
h
dev
->
maxchild
;
i
++
)
portstr
[
i
]
=
hub
->
descriptor
->
DeviceRemovable
[((
i
+
1
)
/
8
)]
&
(
1
<<
((
i
+
1
)
%
8
))
?
'F'
:
'R'
;
portstr
[
dev
->
maxchild
]
=
0
;
portstr
[
h
dev
->
maxchild
]
=
0
;
dev_dbg
(
hub_dev
,
"compound device; port removable status: %s
\n
"
,
portstr
);
}
else
dev_dbg
(
hub_dev
,
"standalone hub
\n
"
);
...
...
@@ -498,32 +497,32 @@ static int hub_configure(struct usb_hub *hub,
spin_lock_init
(
&
hub
->
tt
.
lock
);
INIT_LIST_HEAD
(
&
hub
->
tt
.
clear_list
);
INIT_WORK
(
&
hub
->
tt
.
kevent
,
hub_tt_kevent
,
hub
);
switch
(
dev
->
descriptor
.
bDeviceProtocol
)
{
switch
(
h
dev
->
descriptor
.
bDeviceProtocol
)
{
case
0
:
break
;
case
1
:
dev_dbg
(
hub_dev
,
"Single TT
\n
"
);
hub
->
tt
.
hub
=
dev
;
hub
->
tt
.
hub
=
h
dev
;
break
;
case
2
:
ret
=
usb_set_interface
(
dev
,
0
,
1
);
ret
=
usb_set_interface
(
h
dev
,
0
,
1
);
if
(
ret
==
0
)
{
dev_dbg
(
hub_dev
,
"TT per port
\n
"
);
hub
->
tt
.
multi
=
1
;
}
else
dev_err
(
hub_dev
,
"Using single TT (err %d)
\n
"
,
ret
);
hub
->
tt
.
hub
=
dev
;
hub
->
tt
.
hub
=
h
dev
;
break
;
default:
dev_dbg
(
hub_dev
,
"Unrecognized hub protocol %d
\n
"
,
dev
->
descriptor
.
bDeviceProtocol
);
h
dev
->
descriptor
.
bDeviceProtocol
);
break
;
}
switch
(
hub
->
descriptor
->
wHubCharacteristics
&
HUB_CHAR_TTTT
)
{
case
0x00
:
if
(
dev
->
descriptor
.
bDeviceProtocol
!=
0
)
if
(
h
dev
->
descriptor
.
bDeviceProtocol
!=
0
)
dev_dbg
(
hub_dev
,
"TT requires at most 8 FS bit times
\n
"
);
break
;
case
0x20
:
...
...
@@ -549,9 +548,9 @@ static int hub_configure(struct usb_hub *hub,
/* power budgeting mostly matters with bus-powered hubs,
* and battery-powered root hubs (may provide just 8 mA).
*/
ret
=
usb_get_status
(
dev
,
USB_RECIP_DEVICE
,
0
,
&
hubstatus
);
ret
=
usb_get_status
(
h
dev
,
USB_RECIP_DEVICE
,
0
,
&
hubstatus
);
if
(
ret
<
0
)
{
message
=
"can't get hub
dev
status"
;
message
=
"can't get hub status"
;
goto
fail
;
}
cpu_to_le16s
(
&
hubstatus
);
...
...
@@ -572,7 +571,7 @@ static int hub_configure(struct usb_hub *hub,
}
/* local power status reports aren't always correct */
if
(
dev
->
actconfig
->
desc
.
bmAttributes
&
USB_CONFIG_ATT_SELFPOWER
)
if
(
h
dev
->
actconfig
->
desc
.
bmAttributes
&
USB_CONFIG_ATT_SELFPOWER
)
dev_dbg
(
hub_dev
,
"local power source is %s
\n
"
,
(
hubstatus
&
HUB_STATUS_LOCAL_POWER
)
?
"lost (inactive)"
:
"good"
);
...
...
@@ -582,8 +581,8 @@ static int hub_configure(struct usb_hub *hub,
(
hubstatus
&
HUB_STATUS_OVERCURRENT
)
?
""
:
"no "
);
/* Start the interrupt endpoint */
pipe
=
usb_rcvintpipe
(
dev
,
endpoint
->
bEndpointAddress
);
maxp
=
usb_maxpacket
(
dev
,
pipe
,
usb_pipeout
(
pipe
));
pipe
=
usb_rcvintpipe
(
h
dev
,
endpoint
->
bEndpointAddress
);
maxp
=
usb_maxpacket
(
h
dev
,
pipe
,
usb_pipeout
(
pipe
));
if
(
maxp
>
sizeof
(
*
hub
->
buffer
))
maxp
=
sizeof
(
*
hub
->
buffer
);
...
...
@@ -595,7 +594,7 @@ static int hub_configure(struct usb_hub *hub,
goto
fail
;
}
usb_fill_int_urb
(
hub
->
urb
,
dev
,
pipe
,
*
hub
->
buffer
,
maxp
,
hub_irq
,
usb_fill_int_urb
(
hub
->
urb
,
h
dev
,
pipe
,
*
hub
->
buffer
,
maxp
,
hub_irq
,
hub
,
endpoint
->
bInterval
);
hub
->
urb
->
transfer_dma
=
hub
->
buffer_dma
;
hub
->
urb
->
transfer_flags
|=
URB_NO_TRANSFER_DMA_MAP
;
...
...
@@ -611,7 +610,7 @@ static int hub_configure(struct usb_hub *hub,
/* maybe start cycling the hub leds */
if
(
hub
->
has_indicators
&&
blinkenlights
)
{
set_port_led
(
dev
,
hub
,
1
,
HUB_LED_GREEN
);
set_port_led
(
hdev
,
1
,
HUB_LED_GREEN
);
hub
->
indicator
[
0
]
=
INDICATOR_CYCLE
;
schedule_delayed_work
(
&
hub
->
leds
,
LED_CYCLE_PERIOD
);
}
...
...
@@ -621,7 +620,7 @@ static int hub_configure(struct usb_hub *hub,
return
0
;
fail:
dev_err
(
&
hub
->
intf
->
dev
,
"config failed, %s (err %d)
\n
"
,
dev_err
(
hub_
dev
,
"config failed, %s (err %d)
\n
"
,
message
,
ret
);
/* hub_disconnect() frees urb and descriptor */
return
ret
;
...
...
@@ -693,19 +692,21 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct
usb_host_interface
*
desc
;
struct
usb_endpoint_descriptor
*
endpoint
;
struct
usb_device
*
dev
;
struct
usb_device
*
h
dev
;
struct
usb_hub
*
hub
;
struct
device
*
hub_dev
;
unsigned
long
flags
;
desc
=
intf
->
cur_altsetting
;
dev
=
interface_to_usbdev
(
intf
);
hdev
=
interface_to_usbdev
(
intf
);
hub_dev
=
&
intf
->
dev
;
/* Some hubs have a subclass of 1, which AFAICT according to the */
/* specs is not defined, but it works */
if
((
desc
->
desc
.
bInterfaceSubClass
!=
0
)
&&
(
desc
->
desc
.
bInterfaceSubClass
!=
1
))
{
descriptor_error:
dev_err
(
&
intf
->
dev
,
"bad descriptor, ignoring hub
\n
"
);
dev_err
(
hub_
dev
,
"bad descriptor, ignoring hub
\n
"
);
return
-
EIO
;
}
...
...
@@ -729,11 +730,11 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
}
/* We found a hub */
dev_info
(
hub
dev
(
dev
)
,
"USB hub found
\n
"
);
dev_info
(
hub
_dev
,
"USB hub found
\n
"
);
hub
=
kmalloc
(
sizeof
(
*
hub
),
GFP_KERNEL
);
if
(
!
hub
)
{
dev_dbg
(
hub
dev
(
dev
)
,
"couldn't kmalloc hub struct
\n
"
);
dev_dbg
(
hub
_dev
,
"couldn't kmalloc hub struct
\n
"
);
return
-
ENOMEM
;
}
...
...
@@ -752,7 +753,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
usb_set_intfdata
(
intf
,
hub
);
if
(
dev
->
speed
==
USB_SPEED_HIGH
)
if
(
h
dev
->
speed
==
USB_SPEED_HIGH
)
highspeed_hubs
++
;
if
(
hub_configure
(
hub
,
endpoint
)
>=
0
)
...
...
@@ -765,7 +766,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
static
int
hub_ioctl
(
struct
usb_interface
*
intf
,
unsigned
int
code
,
void
*
user_data
)
{
struct
usb_device
*
h
ub
=
interface_to_usbdev
(
intf
);
struct
usb_device
*
h
dev
=
interface_to_usbdev
(
intf
);
/* assert ifno == 0 (part of hub spec) */
switch
(
code
)
{
...
...
@@ -775,16 +776,16 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
int
i
;
spin_lock_irqsave
(
&
hub_event_lock
,
flags
);
if
(
h
ub
->
devnum
<=
0
)
if
(
h
dev
->
devnum
<=
0
)
info
->
nports
=
0
;
else
{
info
->
nports
=
h
ub
->
maxchild
;
info
->
nports
=
h
dev
->
maxchild
;
for
(
i
=
0
;
i
<
info
->
nports
;
i
++
)
{
if
(
h
ub
->
children
[
i
]
==
NULL
)
if
(
h
dev
->
children
[
i
]
==
NULL
)
info
->
port
[
i
]
=
0
;
else
info
->
port
[
i
]
=
h
ub
->
children
[
i
]
->
devnum
;
h
dev
->
children
[
i
]
->
devnum
;
}
}
spin_unlock_irqrestore
(
&
hub_event_lock
,
flags
);
...
...
@@ -799,13 +800,13 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
static
int
hub_reset
(
struct
usb_hub
*
hub
)
{
struct
usb_device
*
dev
=
interface_to_usbdev
(
hub
->
intf
);
struct
usb_device
*
h
dev
=
interface_to_usbdev
(
hub
->
intf
);
int
i
;
/* Disconnect any attached devices */
for
(
i
=
0
;
i
<
hub
->
descriptor
->
bNbrPorts
;
i
++
)
{
if
(
dev
->
children
[
i
])
usb_disconnect
(
&
dev
->
children
[
i
]);
if
(
h
dev
->
children
[
i
])
usb_disconnect
(
&
h
dev
->
children
[
i
]);
}
/* Attempt to reset the hub */
...
...
@@ -814,10 +815,10 @@ static int hub_reset(struct usb_hub *hub)
else
return
-
1
;
if
(
usb_reset_device
(
dev
))
if
(
usb_reset_device
(
h
dev
))
return
-
1
;
hub
->
urb
->
dev
=
dev
;
hub
->
urb
->
dev
=
h
dev
;
if
(
usb_submit_urb
(
hub
->
urb
,
GFP_KERNEL
))
return
-
1
;
...
...
@@ -826,36 +827,36 @@ static int hub_reset(struct usb_hub *hub)
return
0
;
}
static
void
hub_start_disconnect
(
struct
usb_device
*
dev
)
static
void
hub_start_disconnect
(
struct
usb_device
*
h
dev
)
{
struct
usb_device
*
parent
=
dev
->
parent
;
struct
usb_device
*
parent
=
h
dev
->
parent
;
int
i
;
/* Find the device pointer to disconnect */
if
(
parent
)
{
for
(
i
=
0
;
i
<
parent
->
maxchild
;
i
++
)
{
if
(
parent
->
children
[
i
]
==
dev
)
{
if
(
parent
->
children
[
i
]
==
h
dev
)
{
usb_disconnect
(
&
parent
->
children
[
i
]);
return
;
}
}
}
dev_err
(
&
dev
->
dev
,
"cannot disconnect hub!
\n
"
);
dev_err
(
&
h
dev
->
dev
,
"cannot disconnect hub!
\n
"
);
}
static
int
hub_port_status
(
struct
usb_device
*
dev
,
int
port
,
static
int
hub_port_status
(
struct
usb_device
*
h
dev
,
int
port
,
u16
*
status
,
u16
*
change
)
{
struct
usb_hub
*
hub
=
usb_get_intfdata
(
dev
->
actconfig
->
interface
[
0
]);
struct
usb_hub
*
hub
=
usb_get_intfdata
(
h
dev
->
actconfig
->
interface
[
0
]);
int
ret
;
if
(
!
hub
)
return
-
ENODEV
;
ret
=
get_port_status
(
dev
,
port
+
1
,
&
hub
->
status
->
port
);
ret
=
get_port_status
(
h
dev
,
port
+
1
,
&
hub
->
status
->
port
);
if
(
ret
<
0
)
dev_err
(
hubdev
(
dev
)
,
dev_err
(
&
hub
->
intf
->
dev
,
"%s failed (err = %d)
\n
"
,
__FUNCTION__
,
ret
);
else
{
*
status
=
le16_to_cpu
(
hub
->
status
->
port
.
wPortStatus
);
...
...
@@ -875,9 +876,8 @@ static int hub_port_status(struct usb_device *dev, int port,
#define HUB_LONG_RESET_TIME 200
#define HUB_RESET_TIMEOUT 500
/* return: -1 on error, 0 on success, 1 on disconnect. */
static
int
hub_port_wait_reset
(
struct
usb_device
*
hub
,
int
port
,
struct
usb_device
*
dev
,
unsigned
int
delay
)
static
int
hub_port_wait_reset
(
struct
usb_device
*
hdev
,
int
port
,
struct
usb_device
*
udev
,
unsigned
int
delay
)
{
int
delay_time
,
ret
;
u16
portstatus
;
...
...
@@ -890,28 +890,27 @@ static int hub_port_wait_reset(struct usb_device *hub, int port,
msleep
(
delay
);
/* read and decode port status */
ret
=
hub_port_status
(
hub
,
port
,
&
portstatus
,
&
portchange
);
if
(
ret
<
0
)
{
return
-
1
;
}
ret
=
hub_port_status
(
hdev
,
port
,
&
portstatus
,
&
portchange
);
if
(
ret
<
0
)
return
ret
;
/* Device went away? */
if
(
!
(
portstatus
&
USB_PORT_STAT_CONNECTION
))
return
1
;
return
-
ENOTCONN
;
/* bomb out completely if something weird happened */
if
((
portchange
&
USB_PORT_STAT_C_CONNECTION
))
return
-
1
;
return
-
EINVAL
;
/* if we`ve finished resetting, then break out of the loop */
if
(
!
(
portstatus
&
USB_PORT_STAT_RESET
)
&&
(
portstatus
&
USB_PORT_STAT_ENABLE
))
{
if
(
portstatus
&
USB_PORT_STAT_HIGH_SPEED
)
dev
->
speed
=
USB_SPEED_HIGH
;
u
dev
->
speed
=
USB_SPEED_HIGH
;
else
if
(
portstatus
&
USB_PORT_STAT_LOW_SPEED
)
dev
->
speed
=
USB_SPEED_LOW
;
u
dev
->
speed
=
USB_SPEED_LOW
;
else
dev
->
speed
=
USB_SPEED_FULL
;
u
dev
->
speed
=
USB_SPEED_FULL
;
return
0
;
}
...
...
@@ -919,55 +918,55 @@ static int hub_port_wait_reset(struct usb_device *hub, int port,
if
(
delay_time
>=
2
*
HUB_SHORT_RESET_TIME
)
delay
=
HUB_LONG_RESET_TIME
;
dev_dbg
(
hubdev
(
h
ub
),
dev_dbg
(
hubdev
(
h
dev
),
"port %d not reset yet, waiting %dms
\n
"
,
port
+
1
,
delay
);
}
return
-
1
;
return
-
EBUSY
;
}
/* return: -1 on error, 0 on success, 1 on disconnect. */
static
int
hub_port_reset
(
struct
usb_device
*
hub
,
int
port
,
struct
usb_device
*
dev
,
unsigned
int
delay
)
static
int
hub_port_reset
(
struct
usb_device
*
hdev
,
int
port
,
struct
usb_device
*
udev
,
unsigned
int
delay
)
{
int
i
,
status
;
struct
device
*
hub_dev
=
hubdev
(
hdev
);
/* Reset the port */
for
(
i
=
0
;
i
<
PORT_RESET_TRIES
;
i
++
)
{
set_port_feature
(
h
ub
,
port
+
1
,
USB_PORT_FEAT_RESET
);
set_port_feature
(
h
dev
,
port
+
1
,
USB_PORT_FEAT_RESET
);
/* return on disconnect or reset */
status
=
hub_port_wait_reset
(
h
ub
,
port
,
dev
,
delay
);
if
(
status
!=
-
1
)
{
clear_port_feature
(
h
ub
,
status
=
hub_port_wait_reset
(
h
dev
,
port
,
u
dev
,
delay
);
if
(
status
==
-
ENOTCONN
||
status
==
0
)
{
clear_port_feature
(
h
dev
,
port
+
1
,
USB_PORT_FEAT_C_RESET
);
dev
->
state
=
status
u
dev
->
state
=
status
?
USB_STATE_NOTATTACHED
:
USB_STATE_DEFAULT
;
return
status
;
}
dev_dbg
(
hub
dev
(
hub
)
,
dev_dbg
(
hub
_dev
,
"port %d not enabled, trying reset again...
\n
"
,
port
+
1
);
delay
=
HUB_LONG_RESET_TIME
;
}
dev_err
(
hub
dev
(
hub
)
,
dev_err
(
hub
_dev
,
"Cannot enable port %i. Maybe the USB cable is bad?
\n
"
,
port
+
1
);
return
-
1
;
return
status
;
}
static
int
hub_port_disable
(
struct
usb_device
*
h
ub
,
int
port
)
static
int
hub_port_disable
(
struct
usb_device
*
h
dev
,
int
port
)
{
int
ret
;
ret
=
clear_port_feature
(
h
ub
,
port
+
1
,
USB_PORT_FEAT_ENABLE
);
ret
=
clear_port_feature
(
h
dev
,
port
+
1
,
USB_PORT_FEAT_ENABLE
);
if
(
ret
)
dev_err
(
hubdev
(
h
ub
),
"cannot disable port %d (err = %d)
\n
"
,
dev_err
(
hubdev
(
h
dev
),
"cannot disable port %d (err = %d)
\n
"
,
port
+
1
,
ret
);
return
ret
;
...
...
@@ -991,8 +990,7 @@ static int hub_port_disable(struct usb_device *hub, int port)
#define HUB_DEBOUNCE_STEP 25
#define HUB_DEBOUNCE_STABLE 4
/* return: -1 on error, 0 on success, 1 on disconnect. */
static
int
hub_port_debounce
(
struct
usb_device
*
hub
,
int
port
)
static
int
hub_port_debounce
(
struct
usb_device
*
hdev
,
int
port
)
{
int
ret
;
int
delay_time
,
stable_count
;
...
...
@@ -1004,9 +1002,9 @@ static int hub_port_debounce(struct usb_device *hub, int port)
for
(
delay_time
=
0
;
delay_time
<
HUB_DEBOUNCE_TIMEOUT
;
delay_time
+=
HUB_DEBOUNCE_STEP
)
{
msleep
(
HUB_DEBOUNCE_STEP
);
ret
=
hub_port_status
(
h
ub
,
port
,
&
portstatus
,
&
portchange
);
ret
=
hub_port_status
(
h
dev
,
port
,
&
portstatus
,
&
portchange
);
if
(
ret
<
0
)
return
-
1
;
return
ret
;
if
((
portstatus
&
USB_PORT_STAT_CONNECTION
)
==
connection
)
{
if
(
connection
)
{
...
...
@@ -1019,15 +1017,32 @@ static int hub_port_debounce(struct usb_device *hub, int port)
connection
=
portstatus
&
USB_PORT_STAT_CONNECTION
;
if
((
portchange
&
USB_PORT_STAT_C_CONNECTION
))
{
clear_port_feature
(
h
ub
,
port
+
1
,
USB_PORT_FEAT_C_CONNECTION
);
clear_port_feature
(
h
dev
,
port
+
1
,
USB_PORT_FEAT_C_CONNECTION
);
}
}
dev_dbg
(
hubdev
(
h
ub
),
dev_dbg
(
hubdev
(
h
dev
),
"debounce: port %d: delay %dms stable %d status 0x%x
\n
"
,
port
+
1
,
delay_time
,
stable_count
,
portstatus
);
return
((
portstatus
&
USB_PORT_STAT_CONNECTION
))
?
0
:
1
;
return
(
portstatus
&
USB_PORT_STAT_CONNECTION
)
?
0
:
-
ENOTCONN
;
}
static
int
hub_set_address
(
struct
usb_device
*
udev
)
{
int
retval
;
if
(
udev
->
devnum
==
0
)
return
-
EINVAL
;
if
(
udev
->
state
!=
USB_STATE_DEFAULT
&&
udev
->
state
!=
USB_STATE_ADDRESS
)
return
-
EINVAL
;
retval
=
usb_control_msg
(
udev
,
usb_snddefctrl
(
udev
),
USB_REQ_SET_ADDRESS
,
0
,
udev
->
devnum
,
0
,
NULL
,
0
,
HZ
*
USB_CTRL_SET_TIMEOUT
);
if
(
retval
==
0
)
udev
->
state
=
USB_STATE_ADDRESS
;
return
retval
;
}
/* reset device, (re)assign address, get device descriptor.
...
...
@@ -1039,18 +1054,18 @@ static int hub_port_debounce(struct usb_device *hub, int port)
* config changes and disconnect processing.
*/
static
int
hub_port_init
(
struct
usb_device
*
h
ub
,
struct
usb_device
*
dev
,
int
port
)
hub_port_init
(
struct
usb_device
*
h
dev
,
struct
usb_device
*
u
dev
,
int
port
)
{
static
DECLARE_MUTEX
(
usb_address0_sem
);
int
i
,
j
,
retval
=
-
ENODEV
;
int
i
,
j
,
retval
;
unsigned
delay
=
HUB_SHORT_RESET_TIME
;
enum
usb_device_speed
oldspeed
=
dev
->
speed
;
enum
usb_device_speed
oldspeed
=
u
dev
->
speed
;
/* root hub ports have a slightly longer reset period
* (from USB 2.0 spec, section 7.1.7.5)
*/
if
(
!
h
ub
->
parent
)
if
(
!
h
dev
->
parent
)
delay
=
HUB_ROOT_RESET_TIME
;
/* Some low speed devices have problems with the quick delay, so */
...
...
@@ -1061,24 +1076,21 @@ hub_port_init (struct usb_device *hub, struct usb_device *dev, int port)
down
(
&
usb_address0_sem
);
/* Reset the device; full speed may morph to high speed */
switch
(
hub_port_reset
(
hub
,
port
,
dev
,
delay
))
{
case
0
:
/* success, speed is known */
break
;
case
1
:
/* disconnect, give to companion */
retval
=
-
EBUSY
;
/* FALL THROUGH */
default:
/* error */
retval
=
hub_port_reset
(
hdev
,
port
,
udev
,
delay
);
if
(
retval
<
0
)
/* error or disconnect */
goto
fail
;
}
if
(
oldspeed
!=
USB_SPEED_UNKNOWN
&&
oldspeed
!=
dev
->
speed
)
{
dev_dbg
(
&
dev
->
dev
,
"device reset changed speed!
\n
"
);
/* success, speed is known */
retval
=
-
ENODEV
;
if
(
oldspeed
!=
USB_SPEED_UNKNOWN
&&
oldspeed
!=
udev
->
speed
)
{
dev_dbg
(
&
udev
->
dev
,
"device reset changed speed!
\n
"
);
goto
fail
;
}
/* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
* it's fixed size except for full speed devices.
*/
switch
(
dev
->
speed
)
{
switch
(
u
dev
->
speed
)
{
case
USB_SPEED_HIGH
:
/* fixed at 64 */
i
=
64
;
break
;
...
...
@@ -1094,43 +1106,43 @@ hub_port_init (struct usb_device *hub, struct usb_device *dev, int port)
default:
goto
fail
;
}
dev
->
epmaxpacketin
[
0
]
=
i
;
dev
->
epmaxpacketout
[
0
]
=
i
;
u
dev
->
epmaxpacketin
[
0
]
=
i
;
u
dev
->
epmaxpacketout
[
0
]
=
i
;
/* set the address */
if
(
dev
->
devnum
<=
0
)
{
usb_choose_address
(
dev
);
if
(
dev
->
devnum
<=
0
)
if
(
u
dev
->
devnum
<=
0
)
{
usb_choose_address
(
u
dev
);
if
(
u
dev
->
devnum
<=
0
)
goto
fail
;
/* Set up TT records, if needed */
if
(
h
ub
->
tt
)
{
dev
->
tt
=
hub
->
tt
;
dev
->
ttport
=
hub
->
ttport
;
}
else
if
(
dev
->
speed
!=
USB_SPEED_HIGH
&&
h
ub
->
speed
==
USB_SPEED_HIGH
)
{
struct
usb_hub
*
hub
state
;
if
(
h
dev
->
tt
)
{
udev
->
tt
=
hdev
->
tt
;
udev
->
ttport
=
hdev
->
ttport
;
}
else
if
(
u
dev
->
speed
!=
USB_SPEED_HIGH
&&
h
dev
->
speed
==
USB_SPEED_HIGH
)
{
struct
usb_hub
*
hub
;
hub
state
=
usb_get_intfdata
(
hub
->
actconfig
hub
=
usb_get_intfdata
(
hdev
->
actconfig
->
interface
[
0
]);
dev
->
tt
=
&
hubstate
->
tt
;
dev
->
ttport
=
port
+
1
;
udev
->
tt
=
&
hub
->
tt
;
u
dev
->
ttport
=
port
+
1
;
}
/* force the right log message (below) at low speed */
oldspeed
=
USB_SPEED_UNKNOWN
;
}
dev_info
(
&
dev
->
dev
,
dev_info
(
&
u
dev
->
dev
,
"%s %s speed USB device using address %d
\n
"
,
(
oldspeed
==
USB_SPEED_UNKNOWN
)
?
"new"
:
"reset"
,
({
char
*
speed
;
switch
(
dev
->
speed
)
{
({
char
*
speed
;
switch
(
u
dev
->
speed
)
{
case
USB_SPEED_LOW
:
speed
=
"low"
;
break
;
case
USB_SPEED_FULL
:
speed
=
"full"
;
break
;
case
USB_SPEED_HIGH
:
speed
=
"high"
;
break
;
default:
speed
=
"?"
;
break
;
};
speed
;}),
dev
->
devnum
);
u
dev
->
devnum
);
/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
* Because device hardware and firmware is sometimes buggy in
...
...
@@ -1143,20 +1155,19 @@ hub_port_init (struct usb_device *hub, struct usb_device *dev, int port)
*/
for
(
i
=
0
;
i
<
GET_DESCRIPTOR_TRIES
;
++
i
)
{
for
(
j
=
0
;
j
<
SET_ADDRESS_TRIES
;
++
j
)
{
retval
=
usb_set_address
(
dev
);
retval
=
hub_set_address
(
u
dev
);
if
(
retval
>=
0
)
break
;
msleep
(
200
);
}
if
(
retval
<
0
)
{
dev_err
(
&
dev
->
dev
,
dev_err
(
&
u
dev
->
dev
,
"device not accepting address %d, error %d
\n
"
,
dev
->
devnum
,
retval
);
u
dev
->
devnum
,
retval
);
fail:
hub_port_disable
(
hub
,
port
);
clear_bit
(
dev
->
devnum
,
dev
->
bus
->
devmap
.
devicemap
);
dev
->
devnum
=
-
1
;
usb_put_dev
(
dev
);
hub_port_disable
(
hdev
,
port
);
usb_release_address
(
udev
);
usb_put_dev
(
udev
);
up
(
&
usb_address0_sem
);
return
retval
;
}
...
...
@@ -1166,31 +1177,31 @@ hub_port_init (struct usb_device *hub, struct usb_device *dev, int port)
* - read ep0 maxpacket even for high and low speed,
*/
msleep
(
10
);
retval
=
usb_get_device_descriptor
(
dev
,
8
);
retval
=
usb_get_device_descriptor
(
u
dev
,
8
);
if
(
retval
>=
8
)
break
;
msleep
(
100
);
}
if
(
retval
!=
8
)
{
dev_err
(
&
dev
->
dev
,
"device descriptor read/%s, error %d
\n
"
,
dev_err
(
&
u
dev
->
dev
,
"device descriptor read/%s, error %d
\n
"
,
"8"
,
retval
);
if
(
retval
>=
0
)
retval
=
-
EMSGSIZE
;
goto
fail
;
}
if
(
dev
->
speed
==
USB_SPEED_FULL
&&
(
dev
->
epmaxpacketin
[
0
]
!=
dev
->
descriptor
.
bMaxPacketSize0
))
{
usb_disable_endpoint
(
dev
,
0
);
usb_endpoint_running
(
dev
,
0
,
1
);
usb_endpoint_running
(
dev
,
0
,
0
);
dev
->
epmaxpacketin
[
0
]
=
dev
->
descriptor
.
bMaxPacketSize0
;
dev
->
epmaxpacketout
[
0
]
=
dev
->
descriptor
.
bMaxPacketSize0
;
if
(
u
dev
->
speed
==
USB_SPEED_FULL
&&
(
u
dev
->
epmaxpacketin
[
0
]
!=
u
dev
->
descriptor
.
bMaxPacketSize0
))
{
usb_disable_endpoint
(
u
dev
,
0
);
usb_endpoint_running
(
u
dev
,
0
,
1
);
usb_endpoint_running
(
u
dev
,
0
,
0
);
udev
->
epmaxpacketin
[
0
]
=
u
dev
->
descriptor
.
bMaxPacketSize0
;
udev
->
epmaxpacketout
[
0
]
=
u
dev
->
descriptor
.
bMaxPacketSize0
;
}
retval
=
usb_get_device_descriptor
(
dev
,
USB_DT_DEVICE_SIZE
);
if
(
retval
<
(
signed
)
sizeof
(
dev
->
descriptor
))
{
dev_err
(
&
dev
->
dev
,
"device descriptor read/%s, error %d
\n
"
,
retval
=
usb_get_device_descriptor
(
u
dev
,
USB_DT_DEVICE_SIZE
);
if
(
retval
<
(
signed
)
sizeof
(
u
dev
->
descriptor
))
{
dev_err
(
&
u
dev
->
dev
,
"device descriptor read/%s, error %d
\n
"
,
"all"
,
retval
);
if
(
retval
>=
0
)
retval
=
-
ENOMSG
;
...
...
@@ -1198,14 +1209,14 @@ hub_port_init (struct usb_device *hub, struct usb_device *dev, int port)
}
/* now dev is visible to other tasks */
h
ub
->
children
[
port
]
=
dev
;
h
dev
->
children
[
port
]
=
u
dev
;
up
(
&
usb_address0_sem
);
return
0
;
}
static
void
check_highspeed
(
struct
usb_hub
*
hub
,
struct
usb_device
*
dev
,
int
port
)
check_highspeed
(
struct
usb_hub
*
hub
,
struct
usb_device
*
u
dev
,
int
port
)
{
struct
usb_qualifier_descriptor
*
qual
;
int
status
;
...
...
@@ -1214,10 +1225,10 @@ check_highspeed (struct usb_hub *hub, struct usb_device *dev, int port)
if
(
qual
==
0
)
return
;
status
=
usb_get_descriptor
(
dev
,
USB_DT_DEVICE_QUALIFIER
,
0
,
status
=
usb_get_descriptor
(
u
dev
,
USB_DT_DEVICE_QUALIFIER
,
0
,
qual
,
sizeof
*
qual
);
if
(
status
==
sizeof
*
qual
)
{
dev_info
(
&
dev
->
dev
,
"not running at top speed; "
dev_info
(
&
u
dev
->
dev
,
"not running at top speed; "
"connect to a high speed hub
\n
"
);
/* hub LEDs are probably harder to miss than syslog */
if
(
hub
->
has_indicators
)
{
...
...
@@ -1229,31 +1240,31 @@ check_highspeed (struct usb_hub *hub, struct usb_device *dev, int port)
}
static
unsigned
hub_power_remaining
(
struct
usb_hub
*
hub
state
,
struct
usb_device
*
hub
)
hub_power_remaining
(
struct
usb_hub
*
hub
,
struct
usb_device
*
hdev
)
{
int
remaining
;
unsigned
i
;
remaining
=
hub
state
->
power_budget
;
remaining
=
hub
->
power_budget
;
if
(
!
remaining
)
/* self-powered */
return
0
;
for
(
i
=
0
;
i
<
h
ub
->
maxchild
;
i
++
)
{
struct
usb_device
*
dev
=
hub
->
children
[
i
];
for
(
i
=
0
;
i
<
h
dev
->
maxchild
;
i
++
)
{
struct
usb_device
*
udev
=
hdev
->
children
[
i
];
int
delta
;
if
(
!
dev
)
if
(
!
u
dev
)
continue
;
if
(
dev
->
actconfig
)
delta
=
dev
->
actconfig
->
desc
.
bMaxPower
;
if
(
u
dev
->
actconfig
)
delta
=
u
dev
->
actconfig
->
desc
.
bMaxPower
;
else
delta
=
50
;
// dev_dbg(&dev->dev, "budgeted %dmA\n", 2 * delta);
// dev_dbg(&
u
dev->dev, "budgeted %dmA\n", 2 * delta);
remaining
-=
delta
;
}
if
(
remaining
<
0
)
{
dev_warn
(
&
hub
state
->
intf
->
dev
,
dev_warn
(
&
hub
->
intf
->
dev
,
"%dmA over power budget!
\n
"
,
-
2
*
remaining
);
remaining
=
0
;
...
...
@@ -1261,73 +1272,74 @@ hub_power_remaining (struct usb_hub *hubstate, struct usb_device *hub)
return
remaining
;
}
static
void
hub_port_connect_change
(
struct
usb_hub
*
hub
state
,
int
port
,
static
void
hub_port_connect_change
(
struct
usb_hub
*
hub
,
int
port
,
u16
portstatus
,
u16
portchange
)
{
struct
usb_device
*
hub
=
interface_to_usbdev
(
hubstate
->
intf
);
struct
usb_device
*
hdev
=
interface_to_usbdev
(
hub
->
intf
);
struct
device
*
hub_dev
=
&
hub
->
intf
->
dev
;
int
status
,
i
;
dev_dbg
(
&
hubstate
->
intf
->
dev
,
dev_dbg
(
hub_
dev
,
"port %d, status %04x, change %04x, %s
\n
"
,
port
+
1
,
portstatus
,
portchange
,
portspeed
(
portstatus
));
/* Clear the connection change status */
clear_port_feature
(
h
ub
,
port
+
1
,
USB_PORT_FEAT_C_CONNECTION
);
clear_port_feature
(
h
dev
,
port
+
1
,
USB_PORT_FEAT_C_CONNECTION
);
if
(
hub
state
->
has_indicators
)
{
set_port_led
(
h
ub
,
hubstate
,
port
+
1
,
HUB_LED_AUTO
);
hub
state
->
indicator
[
port
]
=
INDICATOR_AUTO
;
if
(
hub
->
has_indicators
)
{
set_port_led
(
h
dev
,
port
+
1
,
HUB_LED_AUTO
);
hub
->
indicator
[
port
]
=
INDICATOR_AUTO
;
}
/* Disconnect any existing devices under this port */
if
(
h
ub
->
children
[
port
])
usb_disconnect
(
&
h
ub
->
children
[
port
]);
if
(
h
dev
->
children
[
port
])
usb_disconnect
(
&
h
dev
->
children
[
port
]);
/* Return now if nothing is connected */
if
(
!
(
portstatus
&
USB_PORT_STAT_CONNECTION
))
{
/* maybe switch power back on (e.g. root hub was reset) */
if
((
hub
state
->
descriptor
->
wHubCharacteristics
if
((
hub
->
descriptor
->
wHubCharacteristics
&
HUB_CHAR_LPSM
)
<
2
&&
!
(
portstatus
&
(
1
<<
USB_PORT_FEAT_POWER
)))
set_port_feature
(
h
ub
,
port
+
1
,
USB_PORT_FEAT_POWER
);
set_port_feature
(
h
dev
,
port
+
1
,
USB_PORT_FEAT_POWER
);
if
(
portstatus
&
USB_PORT_STAT_ENABLE
)
goto
done
;
return
;
}
if
(
hub_port_debounce
(
h
ub
,
port
))
{
dev_err
(
&
hubstate
->
intf
->
dev
,
if
(
hub_port_debounce
(
h
dev
,
port
))
{
dev_err
(
hub_
dev
,
"connect-debounce failed, port %d disabled
\n
"
,
port
+
1
);
goto
done
;
}
for
(
i
=
0
;
i
<
SET_CONFIG_TRIES
;
i
++
)
{
struct
usb_device
*
dev
;
struct
usb_device
*
u
dev
;
/* reallocate for each attempt, since references
* to the previous one can escape in various ways
*/
dev
=
usb_alloc_dev
(
hub
,
hub
->
bus
,
port
);
if
(
!
dev
)
{
dev_err
(
&
hubstate
->
intf
->
dev
,
udev
=
usb_alloc_dev
(
hdev
,
hdev
->
bus
,
port
);
if
(
!
u
dev
)
{
dev_err
(
hub_
dev
,
"couldn't allocate port %d usb_device
\n
"
,
port
+
1
);
goto
done
;
}
dev
->
state
=
USB_STATE_POWERED
;
u
dev
->
state
=
USB_STATE_POWERED
;
/* hub can tell if it's lowspeed already: D- pullup (not D+) */
if
(
portstatus
&
USB_PORT_STAT_LOW_SPEED
)
dev
->
speed
=
USB_SPEED_LOW
;
u
dev
->
speed
=
USB_SPEED_LOW
;
else
dev
->
speed
=
USB_SPEED_UNKNOWN
;
u
dev
->
speed
=
USB_SPEED_UNKNOWN
;
/* reset, set address, get descriptor, add to hub's children */
down
(
&
dev
->
serialize
);
status
=
hub_port_init
(
h
ub
,
dev
,
port
);
if
(
status
==
-
E
BUSY
)
down
(
&
u
dev
->
serialize
);
status
=
hub_port_init
(
h
dev
,
u
dev
,
port
);
if
(
status
==
-
E
NOTCONN
)
break
;
if
(
status
<
0
)
continue
;
...
...
@@ -1338,50 +1350,50 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
* (without reading syslog), even without per-port LEDs
* on the parent.
*/
if
(
dev
->
descriptor
.
bDeviceClass
==
USB_CLASS_HUB
&&
hub
state
->
power_budget
)
{
if
(
u
dev
->
descriptor
.
bDeviceClass
==
USB_CLASS_HUB
&&
hub
->
power_budget
)
{
u16
devstat
;
status
=
usb_get_status
(
dev
,
USB_RECIP_DEVICE
,
0
,
status
=
usb_get_status
(
u
dev
,
USB_RECIP_DEVICE
,
0
,
&
devstat
);
if
(
status
<
0
)
{
dev_dbg
(
&
dev
->
dev
,
"get status %d ?
\n
"
,
status
);
dev_dbg
(
&
u
dev
->
dev
,
"get status %d ?
\n
"
,
status
);
continue
;
}
cpu_to_le16s
(
&
devstat
);
if
((
devstat
&
(
1
<<
USB_DEVICE_SELF_POWERED
))
==
0
)
{
dev_err
(
&
dev
->
dev
,
dev_err
(
&
u
dev
->
dev
,
"can't connect bus-powered hub "
"to this port
\n
"
);
if
(
hub
state
->
has_indicators
)
{
hub
state
->
indicator
[
port
]
=
if
(
hub
->
has_indicators
)
{
hub
->
indicator
[
port
]
=
INDICATOR_AMBER_BLINK
;
schedule_work
(
&
hub
state
->
leds
);
schedule_work
(
&
hub
->
leds
);
}
h
ub
->
children
[
port
]
=
NULL
;
usb_put_dev
(
dev
);
hub_port_disable
(
h
ub
,
port
);
h
dev
->
children
[
port
]
=
NULL
;
usb_put_dev
(
u
dev
);
hub_port_disable
(
h
dev
,
port
);
return
;
}
}
/* check for devices running slower than they could */
if
(
dev
->
descriptor
.
bcdUSB
>=
0x0200
&&
dev
->
speed
==
USB_SPEED_FULL
if
(
u
dev
->
descriptor
.
bcdUSB
>=
0x0200
&&
u
dev
->
speed
==
USB_SPEED_FULL
&&
highspeed_hubs
!=
0
)
check_highspeed
(
hub
state
,
dev
,
port
);
check_highspeed
(
hub
,
u
dev
,
port
);
/* Run it through the hoops (find a driver, etc) */
status
=
usb_new_device
(
dev
);
status
=
usb_new_device
(
u
dev
);
if
(
status
!=
0
)
{
h
ub
->
children
[
port
]
=
NULL
;
h
dev
->
children
[
port
]
=
NULL
;
continue
;
}
up
(
&
dev
->
serialize
);
up
(
&
u
dev
->
serialize
);
status
=
hub_power_remaining
(
hub
state
,
hub
);
status
=
hub_power_remaining
(
hub
,
hdev
);
if
(
status
)
dev_dbg
(
&
hubstate
->
intf
->
dev
,
dev_dbg
(
hub_
dev
,
"%dmA power budget left
\n
"
,
2
*
status
);
...
...
@@ -1389,15 +1401,16 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
}
done:
hub_port_disable
(
h
ub
,
port
);
hub_port_disable
(
h
dev
,
port
);
}
static
void
hub_events
(
void
)
{
unsigned
long
flags
;
struct
list_head
*
tmp
;
struct
usb_device
*
dev
;
struct
usb_device
*
h
dev
;
struct
usb_hub
*
hub
;
struct
device
*
hub_dev
;
u16
hubstatus
;
u16
hubchange
;
u16
portstatus
;
...
...
@@ -1420,7 +1433,8 @@ static void hub_events(void)
tmp
=
hub_event_list
.
next
;
hub
=
list_entry
(
tmp
,
struct
usb_hub
,
event_list
);
dev
=
interface_to_usbdev
(
hub
->
intf
);
hdev
=
interface_to_usbdev
(
hub
->
intf
);
hub_dev
=
&
hub
->
intf
->
dev
;
list_del_init
(
tmp
);
...
...
@@ -1430,14 +1444,14 @@ static void hub_events(void)
spin_unlock_irqrestore
(
&
hub_event_lock
,
flags
);
if
(
hub
->
error
)
{
dev_dbg
(
&
hub
->
intf
->
dev
,
"resetting for error %d
\n
"
,
dev_dbg
(
hub_
dev
,
"resetting for error %d
\n
"
,
hub
->
error
);
if
(
hub_reset
(
hub
))
{
dev_dbg
(
&
hub
->
intf
->
dev
,
dev_dbg
(
hub_
dev
,
"can't reset; disconnecting
\n
"
);
up
(
&
hub
->
khubd_sem
);
hub_start_disconnect
(
dev
);
hub_start_disconnect
(
h
dev
);
continue
;
}
...
...
@@ -1446,7 +1460,7 @@ static void hub_events(void)
}
for
(
i
=
0
;
i
<
hub
->
descriptor
->
bNbrPorts
;
i
++
)
{
ret
=
hub_port_status
(
dev
,
i
,
&
portstatus
,
&
portchange
);
ret
=
hub_port_status
(
h
dev
,
i
,
&
portstatus
,
&
portchange
);
if
(
ret
<
0
)
{
continue
;
}
...
...
@@ -1454,10 +1468,10 @@ static void hub_events(void)
if
(
portchange
&
USB_PORT_STAT_C_CONNECTION
)
{
hub_port_connect_change
(
hub
,
i
,
portstatus
,
portchange
);
}
else
if
(
portchange
&
USB_PORT_STAT_C_ENABLE
)
{
dev_dbg
(
hub
dev
(
dev
)
,
dev_dbg
(
hub
_dev
,
"port %d enable change, status %08x
\n
"
,
i
+
1
,
portstatus
);
clear_port_feature
(
dev
,
clear_port_feature
(
h
dev
,
i
+
1
,
USB_PORT_FEAT_C_ENABLE
);
/*
...
...
@@ -1468,8 +1482,8 @@ static void hub_events(void)
*/
if
(
!
(
portstatus
&
USB_PORT_STAT_ENABLE
)
&&
(
portstatus
&
USB_PORT_STAT_CONNECTION
)
&&
(
dev
->
children
[
i
]))
{
dev_err
(
&
hub
->
intf
->
dev
,
&&
(
h
dev
->
children
[
i
]))
{
dev_err
(
hub_
dev
,
"port %i "
"disabled by hub (EMI?), "
"re-enabling..."
,
...
...
@@ -1480,43 +1494,43 @@ static void hub_events(void)
}
if
(
portchange
&
USB_PORT_STAT_C_SUSPEND
)
{
dev_dbg
(
&
hub
->
intf
->
dev
,
dev_dbg
(
hub_
dev
,
"suspend change on port %d
\n
"
,
i
+
1
);
clear_port_feature
(
dev
,
clear_port_feature
(
h
dev
,
i
+
1
,
USB_PORT_FEAT_C_SUSPEND
);
}
if
(
portchange
&
USB_PORT_STAT_C_OVERCURRENT
)
{
dev_err
(
&
hub
->
intf
->
dev
,
dev_err
(
hub_
dev
,
"over-current change on port %d
\n
"
,
i
+
1
);
clear_port_feature
(
dev
,
clear_port_feature
(
h
dev
,
i
+
1
,
USB_PORT_FEAT_C_OVER_CURRENT
);
hub_power_on
(
hub
);
}
if
(
portchange
&
USB_PORT_STAT_C_RESET
)
{
dev_dbg
(
&
hub
->
intf
->
dev
,
dev_dbg
(
hub_
dev
,
"reset change on port %d
\n
"
,
i
+
1
);
clear_port_feature
(
dev
,
clear_port_feature
(
h
dev
,
i
+
1
,
USB_PORT_FEAT_C_RESET
);
}
}
/* end for i */
/* deal with hub status changes */
if
(
hub_hub_status
(
hub
,
&
hubstatus
,
&
hubchange
)
<
0
)
dev_err
(
&
hub
->
intf
->
dev
,
"get_hub_status failed
\n
"
);
dev_err
(
hub_
dev
,
"get_hub_status failed
\n
"
);
else
{
if
(
hubchange
&
HUB_CHANGE_LOCAL_POWER
)
{
dev_dbg
(
&
hub
->
intf
->
dev
,
"power change
\n
"
);
clear_hub_feature
(
dev
,
C_HUB_LOCAL_POWER
);
dev_dbg
(
hub_
dev
,
"power change
\n
"
);
clear_hub_feature
(
h
dev
,
C_HUB_LOCAL_POWER
);
}
if
(
hubchange
&
HUB_CHANGE_OVERCURRENT
)
{
dev_dbg
(
&
hub
->
intf
->
dev
,
"overcurrent change
\n
"
);
dev_dbg
(
hub_
dev
,
"overcurrent change
\n
"
);
msleep
(
500
);
/* Cool down */
clear_hub_feature
(
dev
,
C_HUB_OVER_CURRENT
);
clear_hub_feature
(
h
dev
,
C_HUB_OVER_CURRENT
);
hub_power_on
(
hub
);
}
}
...
...
@@ -1526,7 +1540,7 @@ static void hub_events(void)
spin_unlock_irqrestore
(
&
hub_event_lock
,
flags
);
}
static
int
hub_thread
(
void
*
__
hub
)
static
int
hub_thread
(
void
*
__
unused
)
{
/*
* This thread doesn't need any user-level access,
...
...
@@ -1614,36 +1628,36 @@ void usb_hub_cleanup(void)
}
/* usb_hub_cleanup() */
static
int
config_descriptors_changed
(
struct
usb_device
*
dev
)
static
int
config_descriptors_changed
(
struct
usb_device
*
u
dev
)
{
unsigned
index
;
unsigned
len
=
0
;
struct
usb_config_descriptor
*
buf
;
for
(
index
=
0
;
index
<
dev
->
descriptor
.
bNumConfigurations
;
index
++
)
{
if
(
len
<
dev
->
config
[
index
].
desc
.
wTotalLength
)
len
=
dev
->
config
[
index
].
desc
.
wTotalLength
;
for
(
index
=
0
;
index
<
u
dev
->
descriptor
.
bNumConfigurations
;
index
++
)
{
if
(
len
<
u
dev
->
config
[
index
].
desc
.
wTotalLength
)
len
=
u
dev
->
config
[
index
].
desc
.
wTotalLength
;
}
buf
=
kmalloc
(
len
,
SLAB_KERNEL
);
if
(
buf
==
0
)
{
dev_err
(
&
dev
->
dev
,
"no mem to re-read configs after reset
\n
"
);
dev_err
(
&
u
dev
->
dev
,
"no mem to re-read configs after reset
\n
"
);
/* assume the worst */
return
1
;
}
for
(
index
=
0
;
index
<
dev
->
descriptor
.
bNumConfigurations
;
index
++
)
{
for
(
index
=
0
;
index
<
u
dev
->
descriptor
.
bNumConfigurations
;
index
++
)
{
int
length
;
int
old_length
=
dev
->
config
[
index
].
desc
.
wTotalLength
;
int
old_length
=
u
dev
->
config
[
index
].
desc
.
wTotalLength
;
length
=
usb_get_descriptor
(
dev
,
USB_DT_CONFIG
,
index
,
buf
,
length
=
usb_get_descriptor
(
u
dev
,
USB_DT_CONFIG
,
index
,
buf
,
old_length
);
if
(
length
<
old_length
)
{
dev_dbg
(
&
dev
->
dev
,
"config index %d, error %d
\n
"
,
dev_dbg
(
&
u
dev
->
dev
,
"config index %d, error %d
\n
"
,
index
,
length
);
break
;
}
if
(
memcmp
(
buf
,
dev
->
rawdescriptors
[
index
],
old_length
)
if
(
memcmp
(
buf
,
u
dev
->
rawdescriptors
[
index
],
old_length
)
!=
0
)
{
dev_dbg
(
&
dev
->
dev
,
"config index %d changed (#%d)
\n
"
,
dev_dbg
(
&
u
dev
->
dev
,
"config index %d changed (#%d)
\n
"
,
index
,
buf
->
bConfigurationValue
);
/* FIXME enable this when we can re-enumerate after reset;
* until then DFU-ish drivers need this and other workarounds
...
...
@@ -1652,7 +1666,7 @@ static int config_descriptors_changed(struct usb_device *dev)
}
}
kfree
(
buf
);
return
index
!=
dev
->
descriptor
.
bNumConfigurations
;
return
index
!=
u
dev
->
descriptor
.
bNumConfigurations
;
}
/*
...
...
@@ -1664,22 +1678,22 @@ static int config_descriptors_changed(struct usb_device *dev)
* already holds dev->serialize. For example, it's safe to use
* this from a driver probe() routine after downloading new firmware.
*/
int
__usb_reset_device
(
struct
usb_device
*
dev
)
int
__usb_reset_device
(
struct
usb_device
*
u
dev
)
{
struct
usb_device
*
parent
=
dev
->
parent
;
struct
usb_device_descriptor
descriptor
=
dev
->
descriptor
;
struct
usb_device
*
parent
=
u
dev
->
parent
;
struct
usb_device_descriptor
descriptor
=
u
dev
->
descriptor
;
int
i
,
ret
,
port
=
-
1
;
if
(
dev
->
maxchild
)
{
if
(
u
dev
->
maxchild
)
{
/* this requires hub- or hcd-specific logic;
* see hub_reset() and OHCI hc_restart()
*/
dev_dbg
(
&
dev
->
dev
,
"%s for hub!
\n
"
,
__FUNCTION__
);
dev_dbg
(
&
u
dev
->
dev
,
"%s for hub!
\n
"
,
__FUNCTION__
);
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
parent
->
maxchild
;
i
++
)
if
(
parent
->
children
[
i
]
==
dev
)
{
if
(
parent
->
children
[
i
]
==
u
dev
)
{
port
=
i
;
break
;
}
...
...
@@ -1687,45 +1701,45 @@ int __usb_reset_device(struct usb_device *dev)
if
(
port
<
0
)
return
-
ENOENT
;
ret
=
hub_port_init
(
parent
,
dev
,
port
);
ret
=
hub_port_init
(
parent
,
u
dev
,
port
);
if
(
ret
<
0
)
goto
re_enumerate
;
/* Device might have changed firmware (DFU or similar) */
if
(
memcmp
(
&
dev
->
descriptor
,
&
descriptor
,
sizeof
descriptor
)
||
config_descriptors_changed
(
dev
))
{
dev_info
(
&
dev
->
dev
,
"device firmware changed
\n
"
);
dev
->
descriptor
=
descriptor
;
/* for disconnect() calls */
if
(
memcmp
(
&
u
dev
->
descriptor
,
&
descriptor
,
sizeof
descriptor
)
||
config_descriptors_changed
(
u
dev
))
{
dev_info
(
&
u
dev
->
dev
,
"device firmware changed
\n
"
);
u
dev
->
descriptor
=
descriptor
;
/* for disconnect() calls */
goto
re_enumerate
;
}
if
(
!
dev
->
actconfig
)
if
(
!
u
dev
->
actconfig
)
return
0
;
ret
=
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
ret
=
usb_control_msg
(
udev
,
usb_sndctrlpipe
(
u
dev
,
0
),
USB_REQ_SET_CONFIGURATION
,
0
,
dev
->
actconfig
->
desc
.
bConfigurationValue
,
0
,
u
dev
->
actconfig
->
desc
.
bConfigurationValue
,
0
,
NULL
,
0
,
HZ
*
USB_CTRL_SET_TIMEOUT
);
if
(
ret
<
0
)
{
dev_err
(
&
dev
->
dev
,
dev_err
(
&
u
dev
->
dev
,
"can't restore configuration #%d (error=%d)
\n
"
,
dev
->
actconfig
->
desc
.
bConfigurationValue
,
ret
);
u
dev
->
actconfig
->
desc
.
bConfigurationValue
,
ret
);
goto
re_enumerate
;
}
dev
->
state
=
USB_STATE_CONFIGURED
;
u
dev
->
state
=
USB_STATE_CONFIGURED
;
for
(
i
=
0
;
i
<
dev
->
actconfig
->
desc
.
bNumInterfaces
;
i
++
)
{
struct
usb_interface
*
intf
=
dev
->
actconfig
->
interface
[
i
];
for
(
i
=
0
;
i
<
u
dev
->
actconfig
->
desc
.
bNumInterfaces
;
i
++
)
{
struct
usb_interface
*
intf
=
u
dev
->
actconfig
->
interface
[
i
];
struct
usb_interface_descriptor
*
desc
;
/* set_interface resets host side toggle and halt status even
* for altsetting zero. the interface may have no driver.
*/
desc
=
&
intf
->
cur_altsetting
->
desc
;
ret
=
usb_set_interface
(
dev
,
desc
->
bInterfaceNumber
,
ret
=
usb_set_interface
(
u
dev
,
desc
->
bInterfaceNumber
,
desc
->
bAlternateSetting
);
if
(
ret
<
0
)
{
dev_err
(
&
dev
->
dev
,
"failed to restore interface %d "
dev_err
(
&
u
dev
->
dev
,
"failed to restore interface %d "
"altsetting %d (error=%d)
\n
"
,
desc
->
bInterfaceNumber
,
desc
->
bAlternateSetting
,
...
...
@@ -1738,7 +1752,7 @@ int __usb_reset_device(struct usb_device *dev)
re_enumerate:
/* FIXME make some task re-enumerate; don't just mark unusable */
dev
->
state
=
USB_STATE_NOTATTACHED
;
u
dev
->
state
=
USB_STATE_NOTATTACHED
;
return
-
ENODEV
;
}
EXPORT_SYMBOL
(
__usb_reset_device
);
...
...
drivers/usb/core/message.c
View file @
e9b73ef9
...
...
@@ -1252,7 +1252,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
ret
);
continue
;
}
usb_create_
driver
fs_intf_files
(
intf
);
usb_create_
sys
fs_intf_files
(
intf
);
}
}
...
...
drivers/usb/core/
driver
fs.c
→
drivers/usb/core/
sys
fs.c
View file @
e9b73ef9
/*
* drivers/usb/core/
driver
fs.c
* drivers/usb/core/
sys
fs.c
*
* (C) Copyright 2002 David Brownell
* (C) Copyright 2002 Greg Kroah-Hartman
* (C) Copyright 2002 IBM Corp.
*
* All of the
driver
fs file attributes for usb devices and interfaces.
* All of the
sys
fs file attributes for usb devices and interfaces.
*
*/
...
...
@@ -163,7 +163,7 @@ usb_descriptor_attr (bDeviceProtocol, "%02x\n")
usb_descriptor_attr
(
bNumConfigurations
,
"%d
\n
"
)
void
usb_create_
driver
fs_dev_files
(
struct
usb_device
*
udev
)
void
usb_create_
sys
fs_dev_files
(
struct
usb_device
*
udev
)
{
struct
device
*
dev
=
&
udev
->
dev
;
...
...
@@ -217,7 +217,7 @@ usb_intf_attr (bInterfaceSubClass, "%02x\n")
usb_intf_attr
(
bInterfaceProtocol
,
"%02x
\n
"
)
usb_intf_attr
(
iInterface
,
"%02x
\n
"
)
void
usb_create_
driver
fs_intf_files
(
struct
usb_interface
*
intf
)
void
usb_create_
sys
fs_intf_files
(
struct
usb_interface
*
intf
)
{
device_create_file
(
&
intf
->
dev
,
&
dev_attr_bInterfaceNumber
);
device_create_file
(
&
intf
->
dev
,
&
dev_attr_bAlternateSetting
);
...
...
drivers/usb/core/usb.c
View file @
e9b73ef9
...
...
@@ -998,12 +998,10 @@ void usb_disconnect(struct usb_device **pdev)
*/
usb_disable_device
(
dev
,
0
);
dev_dbg
(
&
dev
->
dev
,
"unregistering device
\n
"
);
/* Free the device number and remove the /proc/bus/usb entry */
if
(
dev
->
devnum
>
0
)
{
clear_bit
(
dev
->
devnum
,
dev
->
bus
->
devmap
.
devicemap
);
usbfs_remove_device
(
dev
);
}
dev_dbg
(
&
dev
->
dev
,
"unregistering device
\n
"
);
usb_release_address
(
dev
);
usbfs_remove_device
(
dev
);
up
(
&
dev
->
serialize
);
device_unregister
(
&
dev
->
dev
);
}
...
...
@@ -1038,24 +1036,23 @@ void usb_choose_address(struct usb_device *dev)
}
}
// hub-only!! ... and only exported for reset/reinit path.
// otherwise used internally, for usb_new_device()
int
usb_set_address
(
struct
usb_device
*
dev
)
/**
* usb_release_address - deallocate device address (usbcore-internal)
* @dev: newly removed device
*
* Removes and deallocates the address assigned to a device.
* Only hub drivers (but not virtual root hub drivers for host
* controllers) should ever call this.
*/
void
usb_release_address
(
struct
usb_device
*
dev
)
{
int
retval
;
if
(
dev
->
devnum
==
0
)
return
-
EINVAL
;
if
(
dev
->
state
!=
USB_STATE_DEFAULT
&&
dev
->
state
!=
USB_STATE_ADDRESS
)
return
-
EINVAL
;
retval
=
usb_control_msg
(
dev
,
usb_snddefctrl
(
dev
),
USB_REQ_SET_ADDRESS
,
0
,
dev
->
devnum
,
0
,
NULL
,
0
,
HZ
*
USB_CTRL_SET_TIMEOUT
);
if
(
retval
==
0
)
dev
->
state
=
USB_STATE_ADDRESS
;
return
retval
;
if
(
dev
->
devnum
>
0
)
{
clear_bit
(
dev
->
devnum
,
dev
->
bus
->
devmap
.
devicemap
);
dev
->
devnum
=
-
1
;
}
}
static
inline
void
usb_show_string
(
struct
usb_device
*
dev
,
char
*
id
,
int
index
)
{
char
*
buf
;
...
...
@@ -1069,6 +1066,37 @@ static inline void usb_show_string(struct usb_device *dev, char *id, int index)
kfree
(
buf
);
}
static
int
usb_choose_configuration
(
struct
usb_device
*
dev
)
{
int
c
,
i
;
c
=
dev
->
config
[
0
].
desc
.
bConfigurationValue
;
if
(
dev
->
descriptor
.
bNumConfigurations
!=
1
)
{
for
(
i
=
0
;
i
<
dev
->
descriptor
.
bNumConfigurations
;
i
++
)
{
struct
usb_interface_descriptor
*
desc
;
/* heuristic: Linux is more likely to have class
* drivers, so avoid vendor-specific interfaces.
*/
desc
=
&
dev
->
config
[
i
].
intf_cache
[
0
]
->
altsetting
->
desc
;
if
(
desc
->
bInterfaceClass
==
USB_CLASS_VENDOR_SPEC
)
continue
;
/* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */
if
(
desc
->
bInterfaceClass
==
USB_CLASS_COMM
&&
desc
->
bInterfaceSubClass
==
2
&&
desc
->
bInterfaceProtocol
==
0xff
)
continue
;
c
=
dev
->
config
[
i
].
desc
.
bConfigurationValue
;
break
;
}
dev_info
(
&
dev
->
dev
,
"configuration #%d chosen from %d choices
\n
"
,
c
,
dev
->
descriptor
.
bNumConfigurations
);
}
return
c
;
}
/*
* usb_new_device - perform initial device setup (usbcore-internal)
* @dev: newly addressed device (in ADDRESS state)
...
...
@@ -1090,8 +1118,7 @@ static inline void usb_show_string(struct usb_device *dev, char *id, int index)
int
usb_new_device
(
struct
usb_device
*
dev
)
{
int
err
;
int
i
;
int
config
;
int
c
;
err
=
usb_get_configuration
(
dev
);
if
(
err
<
0
)
{
...
...
@@ -1119,41 +1146,16 @@ int usb_new_device(struct usb_device *dev)
dev_err
(
&
dev
->
dev
,
"can't device_add, error %d
\n
"
,
err
);
goto
fail
;
}
usb_create_
driver
fs_dev_files
(
dev
);
usb_create_
sys
fs_dev_files
(
dev
);
/* 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
++
)
{
struct
usb_interface_descriptor
*
desc
;
/* heuristic: Linux is more likely to have class
* drivers, so avoid vendor-specific interfaces.
*/
desc
=
&
dev
->
config
[
i
].
intf_cache
[
0
]
->
altsetting
->
desc
;
if
(
desc
->
bInterfaceClass
==
USB_CLASS_VENDOR_SPEC
)
continue
;
/* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */
if
(
desc
->
bInterfaceClass
==
USB_CLASS_COMM
&&
desc
->
bInterfaceSubClass
==
2
&&
desc
->
bInterfaceProtocol
==
0xff
)
continue
;
config
=
dev
->
config
[
i
].
desc
.
bConfigurationValue
;
break
;
}
dev_info
(
&
dev
->
dev
,
"configuration #%d chosen from %d choices
\n
"
,
config
,
dev
->
descriptor
.
bNumConfigurations
);
}
err
=
usb_set_configuration
(
dev
,
config
);
c
=
usb_choose_configuration
(
dev
);
err
=
usb_set_configuration
(
dev
,
c
);
if
(
err
)
{
dev_err
(
&
dev
->
dev
,
"can't set config #%d, error %d
\n
"
,
config
,
err
);
dev_err
(
&
dev
->
dev
,
"can't set config #%d, error %d
\n
"
,
c
,
err
);
device_del
(
&
dev
->
dev
);
goto
fail
;
}
...
...
@@ -1166,8 +1168,7 @@ int usb_new_device(struct usb_device *dev)
return
0
;
fail:
dev
->
state
=
USB_STATE_NOTATTACHED
;
clear_bit
(
dev
->
devnum
,
dev
->
bus
->
devmap
.
devicemap
);
dev
->
devnum
=
-
1
;
usb_release_address
(
dev
);
usb_put_dev
(
dev
);
return
err
;
}
...
...
drivers/usb/core/usb.h
View file @
e9b73ef9
/* Functions local to drivers/usb/core/ */
extern
void
usb_create_
driver
fs_dev_files
(
struct
usb_device
*
dev
);
extern
void
usb_create_
driver
fs_intf_files
(
struct
usb_interface
*
intf
);
extern
void
usb_create_
sys
fs_dev_files
(
struct
usb_device
*
dev
);
extern
void
usb_create_
sys
fs_intf_files
(
struct
usb_interface
*
intf
);
extern
int
usb_probe_interface
(
struct
device
*
dev
);
extern
int
usb_unbind_interface
(
struct
device
*
dev
);
...
...
drivers/usb/gadget/Kconfig
View file @
e9b73ef9
...
...
@@ -95,6 +95,7 @@ config USB_PXA2XX
config USB_PXA2XX_SMALL
depends on USB_GADGET_PXA2XX
bool
default n if USB_ETH_RNDIS
default y if USB_ZERO
default y if USB_ETH
default y if USB_G_SERIAL
...
...
drivers/usb/gadget/epautoconf.c
View file @
e9b73ef9
...
...
@@ -96,7 +96,8 @@ ep_matches (
/* for now, avoid PXA "interrupt-in";
* it's documented as never using DATA1.
*/
if
(
gadget_is_pxa
(
gadget
))
if
(
gadget_is_pxa
(
gadget
)
&&
'i'
==
tmp
[
1
])
return
0
;
break
;
case
USB_ENDPOINT_XFER_BULK
:
...
...
drivers/usb/gadget/serial.c
View file @
e9b73ef9
...
...
@@ -154,14 +154,9 @@ do { \
#define GS_CLOSE_TIMEOUT 15
/* debug
macro
*/
/* debug
settings
*/
#if G_SERIAL_DEBUG
static
int
debug
=
G_SERIAL_DEBUG
;
#else
static
int
debug
=
0
;
#endif
#if G_SERIAL_DEBUG
#define gs_debug(format, arg...) \
do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0)
...
...
@@ -598,8 +593,10 @@ MODULE_DESCRIPTION(GS_LONG_NAME);
MODULE_AUTHOR
(
"Al Borchers"
);
MODULE_LICENSE
(
"GPL"
);
#if G_SERIAL_DEBUG
MODULE_PARM
(
debug
,
"i"
);
MODULE_PARM_DESC
(
debug
,
"Enable debugging, 0=off, 1=on"
);
#endif
MODULE_PARM
(
read_q_size
,
"i"
);
MODULE_PARM_DESC
(
read_q_size
,
"Read request queue size, default=32"
);
...
...
drivers/usb/host/uhci-hcd.c
View file @
e9b73ef9
...
...
@@ -95,6 +95,10 @@ static kmem_cache_t *uhci_up_cachep; /* urb_priv */
static
int
uhci_get_current_frame_number
(
struct
uhci_hcd
*
uhci
);
static
int
uhci_urb_dequeue
(
struct
usb_hcd
*
hcd
,
struct
urb
*
urb
);
static
void
uhci_unlink_generic
(
struct
uhci_hcd
*
uhci
,
struct
urb
*
urb
);
static
void
uhci_remove_pending_urbps
(
struct
uhci_hcd
*
uhci
);
static
void
uhci_finish_completion
(
struct
usb_hcd
*
hcd
,
struct
pt_regs
*
regs
);
static
void
uhci_free_pending_qhs
(
struct
uhci_hcd
*
uhci
);
static
void
uhci_free_pending_tds
(
struct
uhci_hcd
*
uhci
);
static
void
hc_state_transitions
(
struct
uhci_hcd
*
uhci
);
...
...
@@ -373,6 +377,7 @@ static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
{
struct
uhci_qh
*
pqh
;
u32
newlink
;
unsigned
int
age
;
if
(
!
qh
)
return
;
...
...
@@ -425,6 +430,12 @@ static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
list_del_init
(
&
qh
->
urbp
->
queue_list
);
qh
->
urbp
=
NULL
;
age
=
uhci_get_current_frame_number
(
uhci
);
if
(
age
!=
uhci
->
qh_remove_age
)
{
uhci_free_pending_qhs
(
uhci
);
uhci
->
qh_remove_age
=
age
;
}
/* Check to see if the remove list is empty. Set the IOC bit */
/* to force an interrupt so we can remove the QH */
if
(
list_empty
(
&
uhci
->
qh_remove_list
))
...
...
@@ -628,6 +639,7 @@ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
{
struct
list_head
*
head
,
*
tmp
;
struct
urb_priv
*
urbp
;
unsigned
int
age
;
urbp
=
(
struct
urb_priv
*
)
urb
->
hcpriv
;
if
(
!
urbp
)
...
...
@@ -637,6 +649,12 @@ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
dev_warn
(
uhci_dev
(
uhci
),
"urb %p still on uhci->urb_list "
"or uhci->remove_list!
\n
"
,
urb
);
age
=
uhci_get_current_frame_number
(
uhci
);
if
(
age
!=
uhci
->
td_remove_age
)
{
uhci_free_pending_tds
(
uhci
);
uhci
->
td_remove_age
=
age
;
}
/* Check to see if the remove list is empty. Set the IOC bit */
/* to force an interrupt so we can remove the TD's*/
if
(
list_empty
(
&
uhci
->
td_remove_list
))
...
...
@@ -1512,6 +1530,7 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
struct
uhci_hcd
*
uhci
=
hcd_to_uhci
(
hcd
);
unsigned
long
flags
;
struct
urb_priv
*
urbp
;
unsigned
int
age
;
spin_lock_irqsave
(
&
uhci
->
schedule_lock
,
flags
);
urbp
=
urb
->
hcpriv
;
...
...
@@ -1521,6 +1540,12 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
uhci_unlink_generic
(
uhci
,
urb
);
age
=
uhci_get_current_frame_number
(
uhci
);
if
(
age
!=
uhci
->
urb_remove_age
)
{
uhci_remove_pending_urbps
(
uhci
);
uhci
->
urb_remove_age
=
age
;
}
/* If we're the first, set the next interrupt bit */
if
(
list_empty
(
&
uhci
->
urb_remove_list
))
uhci_set_next_interrupt
(
uhci
);
...
...
@@ -1590,6 +1615,12 @@ static void stall_callback(unsigned long ptr)
INIT_LIST_HEAD
(
&
list
);
spin_lock_irqsave
(
&
uhci
->
schedule_lock
,
flags
);
if
(
!
list_empty
(
&
uhci
->
urb_remove_list
)
&&
uhci_get_current_frame_number
(
uhci
)
!=
uhci
->
urb_remove_age
)
{
uhci_remove_pending_urbps
(
uhci
);
uhci_finish_completion
(
hcd
,
NULL
);
}
head
=
&
uhci
->
urb_list
;
tmp
=
head
->
next
;
while
(
tmp
!=
head
)
{
...
...
@@ -1728,6 +1759,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
unsigned
int
io_addr
=
uhci
->
io_addr
;
unsigned
short
status
;
struct
list_head
*
tmp
,
*
head
;
unsigned
int
age
;
/*
* Read the interrupt status, and write it back to clear the
...
...
@@ -1758,11 +1790,20 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
spin_lock
(
&
uhci
->
schedule_lock
);
uhci_free_pending_qhs
(
uhci
);
uhci_free_pending_tds
(
uhci
);
uhci_remove_pending_urbps
(
uhci
);
uhci_clear_next_interrupt
(
uhci
);
age
=
uhci_get_current_frame_number
(
uhci
);
if
(
age
!=
uhci
->
qh_remove_age
)
uhci_free_pending_qhs
(
uhci
);
if
(
age
!=
uhci
->
td_remove_age
)
uhci_free_pending_tds
(
uhci
);
if
(
age
!=
uhci
->
urb_remove_age
)
uhci_remove_pending_urbps
(
uhci
);
if
(
list_empty
(
&
uhci
->
urb_remove_list
)
&&
list_empty
(
&
uhci
->
td_remove_list
)
&&
list_empty
(
&
uhci
->
qh_remove_list
))
uhci_clear_next_interrupt
(
uhci
);
else
uhci_set_next_interrupt
(
uhci
);
/* Walk the list of pending URB's to see which ones completed */
head
=
&
uhci
->
urb_list
;
...
...
drivers/usb/host/uhci-hcd.h
View file @
e9b73ef9
...
...
@@ -357,12 +357,15 @@ struct uhci_hcd {
/* List of QH's that are done, but waiting to be unlinked (race) */
struct
list_head
qh_remove_list
;
/* P: uhci->schedule_lock */
unsigned
int
qh_remove_age
;
/* Age in frames */
/* List of TD's that are done, but waiting to be freed (race) */
struct
list_head
td_remove_list
;
/* P: uhci->schedule_lock */
unsigned
int
td_remove_age
;
/* Age in frames */
/* List of asynchronously unlinked URB's */
struct
list_head
urb_remove_list
;
/* P: uhci->schedule_lock */
unsigned
int
urb_remove_age
;
/* Age in frames */
/* List of URB's awaiting completion callback */
struct
list_head
complete_list
;
/* P: uhci->schedule_lock */
...
...
drivers/usb/input/hiddev.c
View file @
e9b73ef9
...
...
@@ -232,7 +232,7 @@ static int hiddev_fasync(int fd, struct file *file, int on)
static
struct
usb_class_driver
hiddev_class
;
static
void
hiddev_cleanup
(
struct
hiddev
*
hiddev
)
{
hiddev_table
[
hiddev
->
hid
->
minor
]
=
NULL
;
hiddev_table
[
hiddev
->
hid
->
minor
-
HIDDEV_MINOR_BASE
]
=
NULL
;
usb_deregister_dev
(
hiddev
->
hid
->
intf
,
&
hiddev_class
);
kfree
(
hiddev
);
}
...
...
drivers/usb/input/powermate.c
View file @
e9b73ef9
...
...
@@ -33,6 +33,7 @@
#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
#define POWERMATE_VENDOR 0x077d
/* Griffin Technology, Inc. */
...
...
@@ -67,7 +68,7 @@ struct powermate_device {
dma_addr_t
configcr_dma
;
struct
usb_device
*
udev
;
struct
input_dev
input
;
s
truct
semaphore
lock
;
s
pinlock_t
lock
;
int
static_brightness
;
int
pulse_speed
;
int
pulse_table
;
...
...
@@ -116,7 +117,7 @@ static void powermate_irq(struct urb *urb, struct pt_regs *regs)
__FUNCTION__
,
retval
);
}
/* Decide if we need to issue a control message and do so. Must be called with pm->lock
dow
n */
/* Decide if we need to issue a control message and do so. Must be called with pm->lock
take
n */
static
void
powermate_sync_state
(
struct
powermate_device
*
pm
)
{
if
(
pm
->
requires_update
==
0
)
...
...
@@ -194,19 +195,22 @@ static void powermate_sync_state(struct powermate_device *pm)
static
void
powermate_config_complete
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
{
struct
powermate_device
*
pm
=
urb
->
context
;
unsigned
long
flags
;
if
(
urb
->
status
)
printk
(
KERN_ERR
"powermate: config urb returned %d
\n
"
,
urb
->
status
);
down
(
&
pm
->
lock
);
spin_lock_irqsave
(
&
pm
->
lock
,
flags
);
powermate_sync_state
(
pm
);
up
(
&
pm
->
lock
);
spin_unlock_irqrestore
(
&
pm
->
lock
,
flags
);
}
/* Set the LED up as described and begin the sync with the hardware if required */
static
void
powermate_pulse_led
(
struct
powermate_device
*
pm
,
int
static_brightness
,
int
pulse_speed
,
int
pulse_table
,
int
pulse_asleep
,
int
pulse_awake
)
{
unsigned
long
flags
;
if
(
pulse_speed
<
0
)
pulse_speed
=
0
;
if
(
pulse_table
<
0
)
...
...
@@ -219,7 +223,8 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne
pulse_asleep
=
!!
pulse_asleep
;
pulse_awake
=
!!
pulse_awake
;
down
(
&
pm
->
lock
);
spin_lock_irqsave
(
&
pm
->
lock
,
flags
);
/* mark state updates which are required */
if
(
static_brightness
!=
pm
->
static_brightness
){
...
...
@@ -242,7 +247,7 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne
powermate_sync_state
(
pm
);
up
(
&
pm
->
lock
);
spin_unlock_irqrestore
(
&
pm
->
lock
,
flags
);
}
/* Callback from the Input layer when an event arrives from userspace to configure the LED */
...
...
@@ -344,7 +349,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
return
-
ENOMEM
;
}
init_MUTEX
(
&
pm
->
lock
)
;
pm
->
lock
=
SPIN_LOCK_UNLOCKED
;
init_input_dev
(
&
pm
->
input
);
/* get a handle to the interrupt data pipe */
...
...
@@ -411,7 +416,6 @@ static void powermate_disconnect(struct usb_interface *intf)
usb_set_intfdata
(
intf
,
NULL
);
if
(
pm
)
{
down
(
&
pm
->
lock
);
pm
->
requires_update
=
0
;
usb_unlink_urb
(
pm
->
irq
);
input_unregister_device
(
&
pm
->
input
);
...
...
drivers/usb/net/kaweth.c
View file @
e9b73ef9
...
...
@@ -1240,20 +1240,21 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
init_waitqueue_head
(
&
awd
.
wqh
);
awd
.
done
=
0
;
set_current_state
(
TASK_INTERRUPTIBLE
);
add_wait_queue
(
&
awd
.
wqh
,
&
wait
);
urb
->
context
=
&
awd
;
status
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
status
=
usb_submit_urb
(
urb
,
GFP_
NOIO
);
if
(
status
)
{
// something went wrong
usb_free_urb
(
urb
);
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
awd
.
wqh
,
&
wait
);
return
status
;
}
while
(
timeout
&&
!
awd
.
done
)
set_current_state
(
TASK_UNINTERRUPTIBLE
);
while
(
timeout
&&
!
awd
.
done
)
{
timeout
=
schedule_timeout
(
timeout
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
}
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
awd
.
wqh
,
&
wait
);
...
...
drivers/usb/net/pegasus.h
View file @
e9b73ef9
...
...
@@ -136,6 +136,7 @@ struct usb_eth_dev {
#define VENDOR_LANEED 0x056e
#define VENDOR_LINKSYS 0x066b
#define VENDOR_MELCO 0x0411
#define VENDOR_MICROSOFT 0x045e
#define VENDOR_MOBILITY 0x1342
#define VENDOR_NETGEAR 0x0846
#define VENDOR_OCT 0x0b39
...
...
@@ -265,6 +266,8 @@ PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005,
DEFAULT_GPIO_RESET
)
PEGASUS_DEV
(
"MELCO/BUFFALO LUA2-TX"
,
VENDOR_MELCO
,
0x0009
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"Microsoft MN-110"
,
VENDOR_MICROSOFT
,
0x007a
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"NETGEAR FA101"
,
VENDOR_NETGEAR
,
0x1020
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"OCT Inc."
,
VENDOR_OCT
,
0x0109
,
...
...
drivers/usb/serial/Kconfig
View file @
e9b73ef9
...
...
@@ -314,8 +314,8 @@ config USB_SERIAL_KLSI
module will be called kl5kusb105.
config USB_SERIAL_KOBIL_SCT
tristate "USB KOBIL chipcard reader
(EXPERIMENTAL)
"
depends on USB_SERIAL
&& EXPERIMENTAL
tristate "USB KOBIL chipcard reader"
depends on USB_SERIAL
---help---
Say Y here if you want to use one of the following KOBIL USB chipcard
readers:
...
...
drivers/usb/serial/ftdi_sio.c
View file @
e9b73ef9
...
...
@@ -17,6 +17,9 @@
* See http://ftdi-usb-sio.sourceforge.net for upto date testing info
* and extra documentation
*
* (27/May/2004) Ian Abbott
* Improved throttling code, mostly stolen from the WhiteHEAT driver.
*
* (26/Mar/2004) Jan Capek
* Added PID's for ICD-U20/ICD-U40 - incircuit PIC debuggers from CCS Inc.
*
...
...
@@ -584,6 +587,10 @@ static struct usb_driver ftdi_driver = {
#define BUFSZ 512
#define PKTSZ 64
/* rx_flags */
#define THROTTLED 0x01
#define ACTUALLY_THROTTLED 0x02
struct
ftdi_private
{
ftdi_chip_type_t
chip_type
;
/* type of the device, either SIO or FT8U232AM */
...
...
@@ -598,6 +605,8 @@ struct ftdi_private {
unsigned
long
last_dtr_rts
;
/* saved modem control outputs */
wait_queue_head_t
delta_msr_wait
;
/* Used for TIOCMIWAIT */
char
prev_status
,
diff_status
;
/* Used for TIOCMIWAIT */
__u8
rx_flags
;
/* receive state flags (throttling) */
spinlock_t
rx_lock
;
/* spinlock for receive state */
int
force_baud
;
/* if non-zero, force the baud rate to this value */
int
force_rtscts
;
/* if non-zero, force RTS-CTS to always be enabled */
...
...
@@ -625,6 +634,7 @@ static int ftdi_write_room (struct usb_serial_port *port);
static
int
ftdi_chars_in_buffer
(
struct
usb_serial_port
*
port
);
static
void
ftdi_write_bulk_callback
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
);
static
void
ftdi_read_bulk_callback
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
);
static
void
ftdi_process_read
(
struct
usb_serial_port
*
port
);
static
void
ftdi_set_termios
(
struct
usb_serial_port
*
port
,
struct
termios
*
old
);
static
int
ftdi_tiocmget
(
struct
usb_serial_port
*
port
,
struct
file
*
file
);
static
int
ftdi_tiocmset
(
struct
usb_serial_port
*
port
,
struct
file
*
file
,
unsigned
int
set
,
unsigned
int
clear
);
...
...
@@ -1110,6 +1120,7 @@ static int ftdi_common_startup (struct usb_serial *serial)
}
memset
(
priv
,
0
,
sizeof
(
*
priv
));
spin_lock_init
(
&
priv
->
rx_lock
);
init_waitqueue_head
(
&
priv
->
delta_msr_wait
);
/* This will push the characters through immediately rather
than queue a task to deliver them */
...
...
@@ -1273,8 +1284,8 @@ static void ftdi_shutdown (struct usb_serial *serial)
*/
if
(
priv
)
{
kfree
(
priv
);
usb_set_serial_port_data
(
port
,
NULL
);
kfree
(
priv
);
}
}
/* ftdi_shutdown */
...
...
@@ -1284,6 +1295,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp)
struct
termios
tmp_termios
;
struct
usb_device
*
dev
=
port
->
serial
->
dev
;
struct
ftdi_private
*
priv
=
usb_get_serial_port_data
(
port
);
unsigned
long
flags
;
int
result
=
0
;
char
buf
[
1
];
/* Needed for the usb_control_msg I think */
...
...
@@ -1317,6 +1329,11 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp)
err
(
"%s Error from RTS HIGH urb"
,
__FUNCTION__
);
}
/* Not throttled */
spin_lock_irqsave
(
&
priv
->
rx_lock
,
flags
);
priv
->
rx_flags
&=
~
(
THROTTLED
|
ACTUALLY_THROTTLED
);
spin_unlock_irqrestore
(
&
priv
->
rx_lock
,
flags
);
/* Start reading from the device */
usb_fill_bulk_urb
(
port
->
read_urb
,
dev
,
usb_rcvbulkpipe
(
dev
,
port
->
bulk_in_endpointAddress
),
...
...
@@ -1370,7 +1387,12 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp)
/* shutdown our bulk read */
if
(
port
->
read_urb
)
{
if
(
usb_unlink_urb
(
port
->
read_urb
)
<
0
)
{
err
(
"Error unlinking read urb"
);
/* Generally, this isn't an error. If the previous
read bulk callback occurred (or is about to occur)
while the port was being closed or was throtted
(and is still throttled), the read urb will not
have been submitted. */
dbg
(
"%s - failed to unlink read urb (generally not an error)"
,
__FUNCTION__
);
}
}
}
/* ftdi_close */
...
...
@@ -1546,13 +1568,6 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
struct
usb_serial_port
*
port
=
(
struct
usb_serial_port
*
)
urb
->
context
;
struct
tty_struct
*
tty
;
struct
ftdi_private
*
priv
;
char
error_flag
;
unsigned
char
*
data
=
urb
->
transfer_buffer
;
int
i
;
int
result
;
int
need_flip
;
int
packet_offset
;
if
(
urb
->
number_of_packets
>
0
)
{
err
(
"%s transfer_buffer_length %d actual_length %d number of packets %d"
,
__FUNCTION__
,
...
...
@@ -1560,7 +1575,7 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
err
(
"%s transfer_flags %x "
,
__FUNCTION__
,
urb
->
transfer_flags
);
}
dbg
(
"%s
"
,
__FUNCTION__
);
dbg
(
"%s
- port %d"
,
__FUNCTION__
,
port
->
number
);
if
(
port
->
open_count
<=
0
)
return
;
...
...
@@ -1572,6 +1587,14 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
}
priv
=
usb_get_serial_port_data
(
port
);
if
(
!
priv
)
{
dbg
(
"%s - bad port private data pointer - exiting"
,
__FUNCTION__
);
return
;
}
if
(
urb
!=
port
->
read_urb
)
{
err
(
"%s - Not my urb!"
,
__FUNCTION__
);
}
if
(
urb
->
status
)
{
/* This will happen at close every time so it is a dbg not an err */
...
...
@@ -1579,6 +1602,59 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
return
;
}
/* If throttled, delay receive processing until unthrottled. */
spin_lock
(
&
priv
->
rx_lock
);
if
(
priv
->
rx_flags
&
THROTTLED
)
{
dbg
(
"Deferring read urb processing until unthrottled"
);
priv
->
rx_flags
|=
ACTUALLY_THROTTLED
;
spin_unlock
(
&
priv
->
rx_lock
);
return
;
}
spin_unlock
(
&
priv
->
rx_lock
);
ftdi_process_read
(
port
);
}
/* ftdi_read_bulk_callback */
static
void
ftdi_process_read
(
struct
usb_serial_port
*
port
)
{
/* ftdi_process_read */
struct
urb
*
urb
;
struct
tty_struct
*
tty
;
struct
ftdi_private
*
priv
;
char
error_flag
;
unsigned
char
*
data
;
int
i
;
int
result
;
int
need_flip
;
int
packet_offset
;
dbg
(
"%s - port %d"
,
__FUNCTION__
,
port
->
number
);
if
(
port
->
open_count
<=
0
)
return
;
tty
=
port
->
tty
;
if
(
!
tty
)
{
dbg
(
"%s - bad tty pointer - exiting"
,
__FUNCTION__
);
return
;
}
priv
=
usb_get_serial_port_data
(
port
);
if
(
!
priv
)
{
dbg
(
"%s - bad port private data pointer - exiting"
,
__FUNCTION__
);
return
;
}
urb
=
port
->
read_urb
;
if
(
!
urb
)
{
dbg
(
"%s - bad read_urb pointer - exiting"
,
__FUNCTION__
);
return
;
}
data
=
urb
->
transfer_buffer
;
/* The first two bytes of every read packet are status */
if
(
urb
->
actual_length
>
2
)
{
usb_serial_debug_data
(
__FILE__
,
__FUNCTION__
,
urb
->
actual_length
,
data
);
...
...
@@ -1683,7 +1759,7 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
}
return
;
}
/* ftdi_
read_bulk_callback
*/
}
/* ftdi_
process_read
*/
static
void
ftdi_break_ctl
(
struct
usb_serial_port
*
port
,
int
break_state
)
...
...
@@ -2073,27 +2149,32 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne
static
void
ftdi_throttle
(
struct
usb_serial_port
*
port
)
{
struct
ftdi_private
*
priv
=
usb_get_serial_port_data
(
port
);
unsigned
long
flags
;
dbg
(
"%s - port %d"
,
__FUNCTION__
,
port
->
number
);
usb_unlink_urb
(
port
->
read_urb
);
spin_lock_irqsave
(
&
priv
->
rx_lock
,
flags
);
priv
->
rx_flags
|=
THROTTLED
;
spin_unlock_irqrestore
(
&
priv
->
rx_lock
,
flags
);
}
static
void
ftdi_unthrottle
(
struct
usb_serial_port
*
port
)
{
int
result
;
struct
ftdi_private
*
priv
=
usb_get_serial_port_data
(
port
);
int
actually_throttled
;
unsigned
long
flags
;
dbg
(
"%s - port %d"
,
__FUNCTION__
,
port
->
number
);
port
->
read_urb
->
dev
=
port
->
serial
->
dev
;
usb_fill_bulk_urb
(
port
->
read_urb
,
port
->
serial
->
dev
,
usb_rcvbulkpipe
(
port
->
serial
->
dev
,
port
->
bulk_in_endpointAddress
),
port
->
read_urb
->
transfer_buffer
,
port
->
read_urb
->
transfer_buffer_length
,
ftdi_read_bulk_callback
,
port
);
spin_lock_irqsave
(
&
priv
->
rx_lock
,
flags
);
actually_throttled
=
priv
->
rx_flags
&
ACTUALLY_THROTTLED
;
priv
->
rx_flags
&=
~
(
THROTTLED
|
ACTUALLY_THROTTLED
);
spin_unlock_irqrestore
(
&
priv
->
rx_lock
,
flags
);
result
=
usb_submit_urb
(
port
->
read_urb
,
GFP_ATOMIC
);
if
(
result
)
err
(
"%s - failed submitting read urb, error %d"
,
__FUNCTION__
,
result
);
if
(
actually_throttled
)
ftdi_process_read
(
port
);
}
static
int
__init
ftdi_init
(
void
)
...
...
drivers/usb/serial/kobil_sct.c
View file @
e9b73ef9
...
...
@@ -21,6 +21,9 @@
* Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus
* (Adapter K), B1 Professional and KAAN Professional (Adapter B)
*
* (21/05/2004) tw
* Fix bug with P'n'P readers
*
* (28/05/2003) tw
* Add support for KAAN SIM
*
...
...
@@ -59,7 +62,7 @@
#include "usb-serial.h"
/* Version Information */
#define DRIVER_VERSION "2
8/05/2003
"
#define DRIVER_VERSION "2
1/05/2004
"
#define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com"
#define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)"
...
...
@@ -339,6 +342,12 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp)
);
dbg
(
"%s - port %d Send reset_all_queues URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
}
if
(
priv
->
device_type
==
KOBIL_USBTWIN_PRODUCT_ID
||
priv
->
device_type
==
KOBIL_ADAPTER_B_PRODUCT_ID
||
priv
->
device_type
==
KOBIL_KAAN_SIM_PRODUCT_ID
)
{
// start reading (Adapter B 'cause PNP string)
result
=
usb_submit_urb
(
port
->
interrupt_in_urb
,
GFP_ATOMIC
);
dbg
(
"%s - port %d Send read URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
}
kfree
(
transfer_buffer
);
return
0
;
...
...
@@ -456,6 +465,11 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
if
(
((
priv
->
device_type
!=
KOBIL_ADAPTER_B_PRODUCT_ID
)
&&
(
priv
->
filled
>
2
)
&&
(
priv
->
filled
>=
(
priv
->
buf
[
1
]
+
3
)))
||
((
priv
->
device_type
==
KOBIL_ADAPTER_B_PRODUCT_ID
)
&&
(
priv
->
filled
>
3
)
&&
(
priv
->
filled
>=
(
priv
->
buf
[
2
]
+
4
)))
)
{
// stop reading (except TWIN and KAAN SIM)
if
(
(
priv
->
device_type
==
KOBIL_ADAPTER_B_PRODUCT_ID
)
||
(
priv
->
device_type
==
KOBIL_ADAPTER_K_PRODUCT_ID
)
)
{
usb_unlink_urb
(
port
->
interrupt_in_urb
);
}
todo
=
priv
->
filled
-
priv
->
cur_pos
;
while
(
todo
>
0
)
{
...
...
@@ -463,25 +477,23 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
length
=
(
todo
<
8
)
?
todo
:
8
;
// copy data to transfer buffer
memcpy
(
port
->
write_urb
->
transfer_buffer
,
priv
->
buf
+
priv
->
cur_pos
,
length
);
usb_fill_bulk_urb
(
port
->
write_urb
,
port
->
serial
->
dev
,
usb_sndbulkpipe
(
port
->
serial
->
dev
,
priv
->
write_int_endpoint_address
)
,
port
->
write_urb
->
transfer_buffer
,
length
,
kobil_write_callback
,
port
usb_fill_int_urb
(
port
->
write_urb
,
port
->
serial
->
dev
,
usb_sndintpipe
(
port
->
serial
->
dev
,
priv
->
write_int_endpoint_address
)
,
port
->
write_urb
->
transfer_buffer
,
length
,
kobil_write_callback
,
port
,
8
);
priv
->
cur_pos
=
priv
->
cur_pos
+
length
;
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
ATOMIC
);
result
=
usb_submit_urb
(
port
->
write_urb
,
GFP_
NOIO
);
dbg
(
"%s - port %d Send write URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
todo
=
priv
->
filled
-
priv
->
cur_pos
;
if
(
todo
>
0
)
{
//mdelay(16);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
24
*
HZ
/
1000
);
msleep
(
24
);
}
}
// end while
...
...
@@ -492,9 +504,14 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
// someone sets the dev to 0 if the close method has been called
port
->
interrupt_in_urb
->
dev
=
port
->
serial
->
dev
;
// start reading
result
=
usb_submit_urb
(
port
->
interrupt_in_urb
,
GFP_ATOMIC
);
dbg
(
"%s - port %d Send read URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
// start reading (except TWIN and KAAN SIM)
if
(
(
priv
->
device_type
==
KOBIL_ADAPTER_B_PRODUCT_ID
)
||
(
priv
->
device_type
==
KOBIL_ADAPTER_K_PRODUCT_ID
)
)
{
// someone sets the dev to 0 if the close method has been called
port
->
interrupt_in_urb
->
dev
=
port
->
serial
->
dev
;
result
=
usb_submit_urb
(
port
->
interrupt_in_urb
,
GFP_NOIO
);
dbg
(
"%s - port %d Send read URB returns: %i"
,
__FUNCTION__
,
port
->
number
,
result
);
}
}
return
count
;
}
...
...
drivers/usb/serial/visor.c
View file @
e9b73ef9
...
...
@@ -680,7 +680,7 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i
char
*
string
;
int
retval
=
0
;
int
i
;
int
num_ports
;
int
num_ports
=
0
;
dbg
(
"%s"
,
__FUNCTION__
);
...
...
@@ -702,41 +702,50 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i
__FUNCTION__
,
retval
);
goto
exit
;
}
connection_info
=
(
struct
visor_connection_info
*
)
transfer_buffer
;
le16_to_cpus
(
&
connection_info
->
num_ports
);
num_ports
=
connection_info
->
num_ports
;
/* handle devices that report invalid stuff here */
if
(
num_ports
>
2
)
num_ports
=
2
;
dev_info
(
dev
,
"%s: Number of ports: %d
\n
"
,
serial
->
type
->
name
,
connection_info
->
num_ports
);
for
(
i
=
0
;
i
<
num_ports
;
++
i
)
{
switch
(
connection_info
->
connections
[
i
].
port_function_id
)
{
case
VISOR_FUNCTION_GENERIC
:
string
=
"Generic"
;
break
;
case
VISOR_FUNCTION_DEBUGGER
:
string
=
"Debugger"
;
break
;
case
VISOR_FUNCTION_HOTSYNC
:
string
=
"HotSync"
;
break
;
case
VISOR_FUNCTION_CONSOLE
:
string
=
"Console"
;
break
;
case
VISOR_FUNCTION_REMOTE_FILE_SYS
:
string
=
"Remote File System"
;
break
;
default:
string
=
"unknown"
;
break
;
if
(
retval
==
sizeof
(
*
connection_info
))
{
connection_info
=
(
struct
visor_connection_info
*
)
transfer_buffer
;
le16_to_cpus
(
&
connection_info
->
num_ports
);
num_ports
=
connection_info
->
num_ports
;
for
(
i
=
0
;
i
<
num_ports
;
++
i
)
{
switch
(
connection_info
->
connections
[
i
].
port_function_id
)
{
case
VISOR_FUNCTION_GENERIC
:
string
=
"Generic"
;
break
;
case
VISOR_FUNCTION_DEBUGGER
:
string
=
"Debugger"
;
break
;
case
VISOR_FUNCTION_HOTSYNC
:
string
=
"HotSync"
;
break
;
case
VISOR_FUNCTION_CONSOLE
:
string
=
"Console"
;
break
;
case
VISOR_FUNCTION_REMOTE_FILE_SYS
:
string
=
"Remote File System"
;
break
;
default:
string
=
"unknown"
;
break
;
}
dev_info
(
dev
,
"%s: port %d, is for %s use
\n
"
,
serial
->
type
->
name
,
connection_info
->
connections
[
i
].
port
,
string
);
}
dev_info
(
dev
,
"%s: port %d, is for %s use
\n
"
,
serial
->
type
->
name
,
connection_info
->
connections
[
i
].
port
,
string
);
}
/*
* Handle devices that report invalid stuff here.
*/
if
(
num_ports
==
0
||
num_ports
>
2
)
{
dev_warn
(
dev
,
"%s: No valid connect info available
\n
"
,
serial
->
type
->
name
);
num_ports
=
2
;
}
dev_info
(
dev
,
"%s: Number of ports: %d
\n
"
,
serial
->
type
->
name
,
num_ports
);
/*
* save off our num_ports info so that we can use it in the
...
...
@@ -868,8 +877,7 @@ static int clie_3_5_startup (struct usb_serial *serial)
static
int
treo_attach
(
struct
usb_serial
*
serial
)
{
struct
usb_serial_port
*
port
;
int
i
;
struct
usb_serial_port
*
swap_port
;
/* Only do this endpoint hack for the Handspring devices with
* interrupt in endpoints, which for now are the Treo devices. */
...
...
@@ -879,31 +887,28 @@ static int treo_attach (struct usb_serial *serial)
dbg
(
"%s"
,
__FUNCTION__
);
/* Ok, this is pretty ugly, but these devices want to use the
* interrupt endpoint as paired up with a bulk endpoint for a
* "virtual serial port". So let's force the endpoints to be
* where we want them to be. */
for
(
i
=
serial
->
num_bulk_in
;
i
<
serial
->
num_ports
;
++
i
)
{
port
=
serial
->
port
[
i
];
port
->
read_urb
=
serial
->
port
[
0
]
->
read_urb
;
port
->
bulk_in_endpointAddress
=
serial
->
port
[
0
]
->
bulk_in_endpointAddress
;
port
->
bulk_in_buffer
=
serial
->
port
[
0
]
->
bulk_in_buffer
;
}
for
(
i
=
serial
->
num_bulk_out
;
i
<
serial
->
num_ports
;
++
i
)
{
port
=
serial
->
port
[
i
];
port
->
write_urb
=
serial
->
port
[
0
]
->
write_urb
;
port
->
bulk_out_size
=
serial
->
port
[
0
]
->
bulk_out_size
;
port
->
bulk_out_endpointAddress
=
serial
->
port
[
0
]
->
bulk_out_endpointAddress
;
port
->
bulk_out_buffer
=
serial
->
port
[
0
]
->
bulk_out_buffer
;
}
for
(
i
=
serial
->
num_interrupt_in
;
i
<
serial
->
num_ports
;
++
i
)
{
port
=
serial
->
port
[
i
];
port
->
interrupt_in_urb
=
serial
->
port
[
0
]
->
interrupt_in_urb
;
port
->
interrupt_in_endpointAddress
=
serial
->
port
[
0
]
->
interrupt_in_endpointAddress
;
port
->
interrupt_in_buffer
=
serial
->
port
[
0
]
->
interrupt_in_buffer
;
}
/*
* It appears that Treos want to use the 1st interrupt endpoint to
* communicate with the 2nd bulk out endpoint, so let's swap the 1st
* and 2nd bulk in and interrupt endpoints. Note that swapping the
* bulk out endpoints would break lots of apps that want to communicate
* on the second port.
*/
#define COPY_PORT(dest, src) \
dest->read_urb = src->read_urb; \
dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress; \
dest->bulk_in_buffer = src->bulk_in_buffer; \
dest->interrupt_in_urb = src->interrupt_in_urb; \
dest->interrupt_in_endpointAddress = src->interrupt_in_endpointAddress; \
dest->interrupt_in_buffer = src->interrupt_in_buffer;
swap_port
=
kmalloc
(
sizeof
(
*
swap_port
),
GFP_KERNEL
);
if
(
!
swap_port
)
return
-
ENOMEM
;
COPY_PORT
(
swap_port
,
serial
->
port
[
0
]);
COPY_PORT
(
serial
->
port
[
0
],
serial
->
port
[
1
]);
COPY_PORT
(
serial
->
port
[
1
],
swap_port
);
kfree
(
swap_port
);
return
0
;
}
...
...
drivers/usb/storage/transport.c
View file @
e9b73ef9
...
...
@@ -1112,8 +1112,7 @@ static int usb_stor_reset_common(struct us_data *us,
/* long wait for reset, so unlock to allow disconnects */
up
(
&
us
->
dev_semaphore
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
*
6
);
msleep
(
6000
);
down
(
&
us
->
dev_semaphore
);
if
(
test_bit
(
US_FLIDX_DISCONNECTING
,
&
us
->
flags
))
{
US_DEBUGP
(
"Reset interrupted by disconnect
\n
"
);
...
...
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