Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
46eb8948
Commit
46eb8948
authored
Dec 01, 2002
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Plain Diff
Merge kroah.com:/home/linux/linux/BK/bleeding-2.5
into kroah.com:/home/linux/linux/BK/gregkh-2.5
parents
114d2a8e
414ca09c
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
231 additions
and
249 deletions
+231
-249
drivers/usb/core/devio.c
drivers/usb/core/devio.c
+24
-35
drivers/usb/core/hcd-pci.c
drivers/usb/core/hcd-pci.c
+18
-13
drivers/usb/core/hcd.c
drivers/usb/core/hcd.c
+3
-8
drivers/usb/core/usb.c
drivers/usb/core/usb.c
+12
-19
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-dbg.c
+25
-21
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hcd.c
+47
-29
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-hub.c
+7
-12
drivers/usb/host/ehci-mem.c
drivers/usb/host/ehci-mem.c
+22
-23
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-q.c
+47
-64
drivers/usb/host/uhci-hcd.c
drivers/usb/host/uhci-hcd.c
+0
-4
drivers/usb/serial/usb-serial.c
drivers/usb/serial/usb-serial.c
+26
-19
drivers/usb/storage/transport.c
drivers/usb/storage/transport.c
+0
-2
No files found.
drivers/usb/core/devio.c
View file @
46eb8948
...
...
@@ -239,18 +239,14 @@ extern __inline__ struct async *async_getpending(struct dev_state *ps, void *use
{
unsigned
long
flags
;
struct
async
*
as
;
struct
list_head
*
p
;
spin_lock_irqsave
(
&
ps
->
lock
,
flags
);
for
(
p
=
ps
->
async_pending
.
next
;
p
!=
&
ps
->
async_pending
;
)
{
as
=
list_entry
(
p
,
struct
async
,
asynclist
);
p
=
p
->
next
;
if
(
as
->
userurb
!=
userurb
)
continue
;
list_del_init
(
&
as
->
asynclist
);
spin_unlock_irqrestore
(
&
ps
->
lock
,
flags
);
return
as
;
}
list_for_each_entry
(
as
,
&
ps
->
async_pending
,
asynclist
)
if
(
as
->
userurb
==
userurb
)
{
list_del_init
(
&
as
->
asynclist
);
spin_unlock_irqrestore
(
&
ps
->
lock
,
flags
);
return
as
;
}
spin_unlock_irqrestore
(
&
ps
->
lock
,
flags
);
return
NULL
;
}
...
...
@@ -295,19 +291,14 @@ static void destroy_async (struct dev_state *ps, struct list_head *list)
static
void
destroy_async_on_interface
(
struct
dev_state
*
ps
,
unsigned
int
intf
)
{
struct
async
*
as
;
struct
list_head
*
p
,
hitlist
;
struct
list_head
*
p
,
*
q
,
hitlist
;
unsigned
long
flags
;
INIT_LIST_HEAD
(
&
hitlist
);
spin_lock_irqsave
(
&
ps
->
lock
,
flags
);
for
(
p
=
ps
->
async_pending
.
next
;
p
!=
&
ps
->
async_pending
;
)
{
as
=
list_entry
(
p
,
struct
async
,
asynclist
);
p
=
p
->
next
;
if
(
as
->
intf
==
intf
)
list_move_tail
(
&
as
->
asynclist
,
&
hitlist
);
}
list_for_each_safe
(
p
,
q
,
&
ps
->
async_pending
)
if
(
intf
==
list_entry
(
p
,
struct
async
,
asynclist
)
->
intf
)
list_move_tail
(
p
,
&
hitlist
);
spin_unlock_irqrestore
(
&
ps
->
lock
,
flags
);
destroy_async
(
ps
,
&
hitlist
);
}
...
...
@@ -869,7 +860,7 @@ static int proc_submiturb(struct dev_state *ps, void *arg)
if
(
uurb
.
buffer_length
>
16384
)
return
-
EINVAL
;
if
(
!
access_ok
((
uurb
.
endpoint
&
USB_DIR_IN
)
?
VERIFY_WRITE
:
VERIFY_READ
,
uurb
.
buffer
,
uurb
.
buffer_length
))
return
-
EFAULT
;
return
-
EFAULT
;
break
;
default:
...
...
@@ -964,10 +955,10 @@ static int processcompl(struct async *as)
if
(
!
(
usb_pipeisoc
(
urb
->
pipe
)))
return
0
;
for
(
i
=
0
;
i
<
urb
->
number_of_packets
;
i
++
)
{
if
(
put_user
(
urb
->
iso_frame_desc
[
i
].
actual_length
,
if
(
put_user
(
urb
->
iso_frame_desc
[
i
].
actual_length
,
&
((
struct
usbdevfs_urb
*
)
as
->
userurb
)
->
iso_frame_desc
[
i
].
actual_length
))
return
-
EFAULT
;
if
(
put_user
(
urb
->
iso_frame_desc
[
i
].
status
,
if
(
put_user
(
urb
->
iso_frame_desc
[
i
].
status
,
&
((
struct
usbdevfs_urb
*
)
as
->
userurb
)
->
iso_frame_desc
[
i
].
status
))
return
-
EFAULT
;
}
...
...
@@ -1099,12 +1090,10 @@ static int proc_ioctl (struct dev_state *ps, void *arg)
else
switch
(
ctrl
.
ioctl_code
)
{
/* disconnect kernel driver from interface, leaving it unbound. */
/* maybe unbound - you get no guarantee it stays unbound */
case
USBDEVFS_DISCONNECT
:
/* this function is voodoo. */
/* which function ... usb_device_remove()?
* FIXME either the module lock (BKL) should be involved
* here too, or the 'default' case below is broken
*/
/* this function is misdesigned - retained for compatibility */
lock_kernel
();
driver
=
ifp
->
driver
;
if
(
driver
)
{
dbg
(
"disconnect '%s' from dev %d interface %d"
,
...
...
@@ -1112,11 +1101,14 @@ static int proc_ioctl (struct dev_state *ps, void *arg)
usb_device_remove
(
&
ifp
->
dev
);
}
else
retval
=
-
ENODATA
;
unlock_kernel
();
break
;
/* let kernel drivers try to (re)bind to the interface */
case
USBDEVFS_CONNECT
:
lock_kernel
();
retval
=
usb_device_probe
(
&
ifp
->
dev
);
unlock_kernel
();
break
;
/* talk directly to the interface's driver */
...
...
@@ -1131,20 +1123,17 @@ static int proc_ioctl (struct dev_state *ps, void *arg)
unlock_kernel
();
retval
=
-
ENOSYS
;
}
else
{
if
(
driver
->
owner
&&
!
try_inc_mod_count
(
driver
->
owner
))
{
if
(
!
try_module_get
(
driver
->
owner
))
{
unlock_kernel
();
retval
=
-
ENOSYS
;
break
;
}
unlock_kernel
();
retval
=
driver
->
ioctl
(
ifp
,
ctrl
.
ioctl_code
,
buf
);
if
(
driver
->
owner
)
__MOD_DEC_USE_COUNT
(
driver
->
owner
);
if
(
retval
==
-
ENOIOCTLCMD
)
retval
=
-
ENOTTY
;
module_put
(
driver
->
owner
);
}
if
(
retval
==
-
ENOIOCTLCMD
)
retval
=
-
ENOTTY
;
}
/* cleanup and return */
...
...
@@ -1197,7 +1186,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
case
USBDEVFS_RESET
:
ret
=
proc_resetdevice
(
ps
);
break
;
case
USBDEVFS_CLEAR_HALT
:
ret
=
proc_clearhalt
(
ps
,
(
void
*
)
arg
);
if
(
ret
>=
0
)
...
...
drivers/usb/core/hcd-pci.c
View file @
46eb8948
...
...
@@ -146,7 +146,7 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
goto
clean_2
;
}
info
(
"%s @ %s, %s"
,
hcd
->
description
,
dev
->
slot_name
,
dev
->
dev
.
name
);
dev_info
(
*
hcd
->
controller
,
"%s
\n
"
,
hcd
->
product_desc
);
#ifndef __sparc__
sprintf
(
buf
,
"%d"
,
dev
->
irq
);
...
...
@@ -155,7 +155,8 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
#endif
if
(
request_irq
(
dev
->
irq
,
usb_hcd_irq
,
SA_SHIRQ
,
hcd
->
description
,
hcd
)
!=
0
)
{
err
(
"request interrupt %s failed"
,
bufp
);
dev_err
(
*
hcd
->
controller
,
"request interrupt %s failed
\n
"
,
bufp
);
retval
=
-
EBUSY
;
goto
clean_3
;
}
...
...
@@ -163,7 +164,7 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
hcd
->
regs
=
base
;
hcd
->
region
=
region
;
info
(
"irq %s, %s %p
"
,
bufp
,
dev_info
(
*
hcd
->
controller
,
"irq %s, %s %p
\n
"
,
bufp
,
(
driver
->
flags
&
HCD_MEMORY
)
?
"pci mem"
:
"io base"
,
base
);
...
...
@@ -205,19 +206,20 @@ void usb_hcd_pci_remove (struct pci_dev *dev)
hcd
=
pci_get_drvdata
(
dev
);
if
(
!
hcd
)
return
;
info
(
"remove: %s, state %x"
,
hcd
->
self
.
bus_name
,
hcd
->
state
);
dev_info
(
*
hcd
->
controller
,
"remove, state %x
\n
"
,
hcd
->
state
);
if
(
in_interrupt
())
BUG
();
hub
=
hcd
->
self
.
root_hub
;
hcd
->
state
=
USB_STATE_QUIESCING
;
d
bg
(
"%s: roothub graceful disconnect"
,
hcd
->
self
.
bus_name
);
d
ev_dbg
(
*
hcd
->
controller
,
"roothub graceful disconnect
\n
"
);
usb_disconnect
(
&
hub
);
hcd
->
driver
->
stop
(
hcd
);
hcd_buffer_destroy
(
hcd
);
hcd
->
state
=
USB_STATE_HALT
;
pci_set_drvdata
(
dev
,
0
);
free_irq
(
hcd
->
irq
,
hcd
);
if
(
hcd
->
driver
->
flags
&
HCD_MEMORY
)
{
...
...
@@ -230,9 +232,12 @@ void usb_hcd_pci_remove (struct pci_dev *dev)
}
usb_deregister_bus
(
&
hcd
->
self
);
if
(
atomic_read
(
&
hcd
->
self
.
refcnt
)
!=
1
)
err
(
"usb_hcd_pci_remove %s, count != 1"
,
hcd
->
self
.
bus_name
);
if
(
atomic_read
(
&
hcd
->
self
.
refcnt
)
!=
1
)
{
dev_warn
(
*
hcd
->
controller
,
"dangling refs (%d) to bus %d!
\n
"
,
atomic_read
(
&
hcd
->
self
.
refcnt
)
-
1
,
hcd
->
self
.
busnum
);
}
hcd
->
driver
->
hcd_free
(
hcd
);
}
EXPORT_SYMBOL
(
usb_hcd_pci_remove
);
...
...
@@ -279,7 +284,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state)
int
retval
;
hcd
=
pci_get_drvdata
(
dev
);
info
(
"suspend %s to state %d"
,
hcd
->
self
.
bus_name
,
state
);
dev_info
(
*
hcd
->
controller
,
"suspend to state %d
\n
"
,
state
);
pci_save_state
(
dev
,
hcd
->
pci_state
);
...
...
@@ -308,19 +313,19 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
int
retval
;
hcd
=
pci_get_drvdata
(
dev
);
info
(
"resume %s"
,
hcd
->
self
.
bus_name
);
dev_info
(
*
hcd
->
controller
,
"resume
\n
"
);
/* guard against multiple resumes (APM bug?) */
atomic_inc
(
&
hcd
->
resume_count
);
if
(
atomic_read
(
&
hcd
->
resume_count
)
!=
1
)
{
err
(
"concurrent PCI resumes for %s"
,
hcd
->
self
.
bus_name
);
dev_err
(
*
hcd
->
controller
,
"concurrent PCI resumes
\n
"
);
retval
=
0
;
goto
done
;
}
retval
=
-
EBUSY
;
if
(
hcd
->
state
!=
USB_STATE_SUSPENDED
)
{
d
bg
(
"can't resume, not suspended!
"
);
d
ev_dbg
(
*
hcd
->
controller
,
"can't resume, not suspended!
\n
"
);
goto
done
;
}
hcd
->
state
=
USB_STATE_RESUMING
;
...
...
@@ -330,7 +335,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
retval
=
hcd
->
driver
->
resume
(
hcd
);
if
(
!
HCD_IS_RUNNING
(
hcd
->
state
))
{
d
bg
(
"resume %s failure, retval %d"
,
hcd
->
self
.
bus_name
,
retval
);
d
ev_dbg
(
*
hcd
->
controller
,
"resume fail, retval %d
\n
"
,
retval
);
usb_hc_died
(
hcd
);
// FIXME: recover, reset etc.
}
else
{
...
...
drivers/usb/core/hcd.c
View file @
46eb8948
...
...
@@ -715,7 +715,8 @@ int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev
sprintf
(
&
usb_dev
->
dev
.
bus_id
[
0
],
"usb%d"
,
usb_dev
->
bus
->
busnum
);
retval
=
usb_new_device
(
usb_dev
,
parent_dev
);
if
(
retval
)
err
(
"%s - usb_new_device failed with value %d"
,
__FUNCTION__
,
retval
);
dev_err
(
*
parent_dev
,
"can't register root hub for %s, %d
\n
"
,
usb_dev
->
dev
.
bus_id
,
retval
);
return
retval
;
}
EXPORT_SYMBOL
(
usb_register_root_hub
);
...
...
@@ -1286,13 +1287,7 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb)
// NOTE: a generic device/urb monitoring hook would go here.
// hcd_monitor_hook(MONITOR_URB_FINISH, urb, dev)
// It would catch exit/unlink paths for all urbs, but non-exit
// completions for periodic urbs need hooks inside the HCD.
// hcd_monitor_hook(MONITOR_URB_UPDATE, urb, dev)
if
(
urb
->
status
)
dbg
(
"giveback urb %p status %d len %d"
,
urb
,
urb
->
status
,
urb
->
actual_length
);
// It would catch exit/unlink paths for all urbs.
/* lower level hcd code should use *_dma exclusively */
if
(
!
(
urb
->
transfer_flags
&
URB_NO_DMA_MAP
))
{
...
...
drivers/usb/core/usb.c
View file @
46eb8948
...
...
@@ -69,24 +69,23 @@ static struct device_driver usb_generic_driver = {
.
probe
=
generic_probe
,
.
remove
=
generic_remove
,
};
/* needs to be called with BKL held */
int
usb_device_probe
(
struct
device
*
dev
)
{
struct
usb_interface
*
intf
=
to_usb_interface
(
dev
);
struct
usb_driver
*
driver
=
to_usb_driver
(
dev
->
driver
);
const
struct
usb_device_id
*
id
;
int
error
=
-
ENODEV
;
int
m
;
dbg
(
"%s"
,
__FUNCTION__
);
if
(
!
driver
->
probe
)
return
error
;
if
(
driver
->
owner
)
{
m
=
try_inc_mod_count
(
driver
->
owner
);
if
(
m
==
0
)
return
error
;
if
(
!
try_module_get
(
driver
->
owner
))
{
err
(
"Can't get a module reference for %s"
,
driver
->
name
);
return
error
;
}
id
=
usb_match_id
(
intf
,
driver
->
id_table
);
...
...
@@ -99,8 +98,7 @@ int usb_device_probe(struct device *dev)
if
(
!
error
)
intf
->
driver
=
driver
;
if
(
driver
->
owner
)
__MOD_DEC_USE_COUNT
(
driver
->
owner
);
module_put
(
driver
->
owner
);
return
error
;
}
...
...
@@ -109,7 +107,6 @@ int usb_device_remove(struct device *dev)
{
struct
usb_interface
*
intf
;
struct
usb_driver
*
driver
;
int
m
;
intf
=
list_entry
(
dev
,
struct
usb_interface
,
dev
);
driver
=
to_usb_driver
(
dev
->
driver
);
...
...
@@ -120,14 +117,11 @@ int usb_device_remove(struct device *dev)
return
-
ENODEV
;
}
if
(
driver
->
owner
)
{
m
=
try_inc_mod_count
(
driver
->
owner
);
if
(
m
==
0
)
{
// FIXME this happens even when we just rmmod
// drivers that aren't in active use...
err
(
"Dieing driver still bound to device.
\n
"
);
return
-
EIO
;
}
if
(
!
try_module_get
(
driver
->
owner
))
{
// FIXME this happens even when we just rmmod
// drivers that aren't in active use...
err
(
"Dieing driver still bound to device.
\n
"
);
return
-
EIO
;
}
/* if we sleep here on an umanaged driver
...
...
@@ -143,8 +137,7 @@ int usb_device_remove(struct device *dev)
usb_driver_release_interface
(
driver
,
intf
);
up
(
&
driver
->
serialize
);
if
(
driver
->
owner
)
__MOD_DEC_USE_COUNT
(
driver
->
owner
);
module_put
(
driver
->
owner
);
return
0
;
}
...
...
drivers/usb/host/ehci-dbg.c
View file @
46eb8948
...
...
@@ -18,6 +18,17 @@
/* this file is part of ehci-hcd.c */
#define ehci_dbg(ehci, fmt, args...) \
dev_dbg (*(ehci)->hcd.controller, fmt, ## args )
#ifdef EHCI_VERBOSE_DEBUG
#define ehci_vdbg(ehci, fmt, args...) \
dev_dbg (*(ehci)->hcd.controller, fmt, ## args )
#else
#define ehci_vdbg(ehci, fmt, args...) do { } while (0)
#endif
#ifdef EHCI_VERBOSE_DEBUG
# define vdbg dbg
#else
...
...
@@ -34,7 +45,8 @@ static void dbg_hcs_params (struct ehci_hcd *ehci, char *label)
{
u32
params
=
readl
(
&
ehci
->
caps
->
hcs_params
);
dbg
(
"%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d"
,
ehci_dbg
(
ehci
,
"%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d
\n
"
,
label
,
params
,
HCS_DEBUG_PORT
(
params
),
HCS_INDICATOR
(
params
)
?
" ind"
:
""
,
...
...
@@ -56,9 +68,8 @@ static void dbg_hcs_params (struct ehci_hcd *ehci, char *label)
((
i
&
0x1
)
?
((
byte
)
&
0xf
)
:
((
byte
>>
4
)
&
0xf
)));
strcat
(
buf
,
tmp
);
}
dbg
(
"%s: %s portroute %s"
,
hcd_to_bus
(
&
ehci
->
hcd
)
->
bus_name
,
label
,
buf
);
ehci_dbg
(
ehci
,
"%s portroute %s
\n
"
,
label
,
buf
);
}
}
#else
...
...
@@ -77,19 +88,16 @@ static void dbg_hcc_params (struct ehci_hcd *ehci, char *label)
{
u32
params
=
readl
(
&
ehci
->
caps
->
hcc_params
);
if
(
HCC_EXT_CAPS
(
params
))
{
// EHCI 0.96 ... could interpret these (legacy?)
dbg
(
"%s extended capabilities at pci %2x"
,
label
,
HCC_EXT_CAPS
(
params
));
}
if
(
HCC_ISOC_CACHE
(
params
))
{
dbg
(
"%s hcc_params %04x caching frame %s%s%s"
,
ehci_dbg
(
ehci
,
"%s hcc_params %04x caching frame %s%s%s
\n
"
,
label
,
params
,
HCC_PGM_FRAMELISTLEN
(
params
)
?
"256/512/1024"
:
"1024"
,
HCC_CANPARK
(
params
)
?
" park"
:
""
,
HCC_64BIT_ADDR
(
params
)
?
" 64 bit addr"
:
""
);
}
else
{
dbg
(
"%s hcc_params %04x caching %d uframes %s%s%s"
,
ehci_dbg
(
ehci
,
"%s hcc_params %04x thresh %d uframes %s%s%s
\n
"
,
label
,
params
,
HCC_ISOC_THRES
(
params
),
...
...
@@ -235,19 +243,19 @@ dbg_port_buf (char *buf, unsigned len, char *label, int port, u32 status)
#define dbg_status(ehci, label, status) { \
char _buf [80]; \
dbg_status_buf (_buf, sizeof _buf, label, status); \
dbg ("%s
", _buf); \
ehci_dbg (ehci, "%s\n
", _buf); \
}
#define dbg_cmd(ehci, label, command) { \
char _buf [80]; \
dbg_command_buf (_buf, sizeof _buf, label, command); \
dbg ("%s
", _buf); \
ehci_dbg (ehci, "%s\n
", _buf); \
}
#define dbg_port(
hcd
, label, port, status) { \
#define dbg_port(
ehci
, label, port, status) { \
char _buf [80]; \
dbg_port_buf (_buf, sizeof _buf, label, port, status); \
dbg ("%s
", _buf); \
ehci_dbg (ehci, "%s\n
", _buf); \
}
/*-------------------------------------------------------------------------*/
...
...
@@ -338,12 +346,8 @@ show_async (struct device *dev, char *buf, size_t count, loff_t off)
* one QH per line, and TDs we know about
*/
spin_lock_irqsave
(
&
ehci
->
lock
,
flags
);
if
(
ehci
->
async
)
{
qh
=
ehci
->
async
;
do
{
qh_lines
(
qh
,
&
next
,
&
size
);
}
while
((
qh
=
qh
->
qh_next
.
qh
)
!=
ehci
->
async
);
}
for
(
qh
=
ehci
->
async
->
qh_next
.
qh
;
qh
;
qh
=
qh
->
qh_next
.
qh
)
qh_lines
(
qh
,
&
next
,
&
size
);
if
(
ehci
->
reclaim
)
{
temp
=
snprintf
(
next
,
size
,
"
\n
reclaim =
\n
"
);
size
-=
temp
;
...
...
drivers/usb/host/ehci-hcd.c
View file @
46eb8948
...
...
@@ -17,6 +17,13 @@
*/
#include <linux/config.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h>
...
...
@@ -31,12 +38,6 @@
#include <linux/list.h>
#include <linux/interrupt.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/usb.h>
#include <linux/version.h>
...
...
@@ -70,6 +71,7 @@
*
* HISTORY:
*
* 2002-11-29 Correct handling for hw async_next register.
* 2002-08-06 Handling for bulk and interrupt transfers is mostly shared;
* only scheduling is different, no arbitrary limitations.
* 2002-07-25 Sanity check PCI reads, mostly for better cardbus support,
...
...
@@ -92,7 +94,7 @@
* 2001-June Works with usb-storage and NEC EHCI on 2.4
*/
#define DRIVER_VERSION "2002-
Sep-23
"
#define DRIVER_VERSION "2002-
Nov-29
"
#define DRIVER_AUTHOR "David Brownell"
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
...
...
@@ -114,7 +116,7 @@ static const char hcd_name [] = "ehci-hcd";
#define EHCI_TUNE_MULT_TT 1
#define EHCI_WATCHDOG_JIFFIES (HZ/100)
/* arbitrary; ~10 msec */
#define EHCI_ASYNC_JIFFIES (HZ/
3
)
/* async idle timeout */
#define EHCI_ASYNC_JIFFIES (HZ/
20
)
/* async idle timeout */
/* Initial IRQ latency: lower than default */
static
int
log2_irq_thresh
=
0
;
// 0 to 6
...
...
@@ -215,7 +217,7 @@ static void ehci_ready (struct ehci_hcd *ehci)
/* wait for any schedule enables/disables to take effect */
temp
=
0
;
if
(
ehci
->
async
)
if
(
ehci
->
async
->
qh_next
.
qh
)
temp
=
STS_ASS
;
if
(
ehci
->
next_uframe
!=
-
1
)
temp
|=
STS_PSS
;
...
...
@@ -260,7 +262,7 @@ static void ehci_watchdog (unsigned long param)
spin_lock_irqsave
(
&
ehci
->
lock
,
flags
);
/* guard against lost IAA, which wedges everything */
ehci_irq
(
&
ehci
->
hcd
);
/*
unlink the last qh
after it's idled a while */
/*
stop async processing
after it's idled a while */
if
(
ehci
->
async_idle
)
{
start_unlink_async
(
ehci
,
ehci
->
async
);
ehci
->
async_idle
=
0
;
...
...
@@ -287,12 +289,13 @@ static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap)
pci_read_config_dword
(
ehci
->
hcd
.
pdev
,
where
,
&
cap
);
}
while
((
cap
&
(
1
<<
16
))
&&
msec
);
if
(
cap
&
(
1
<<
16
))
{
info
(
"BIOS handoff failed (%d, %04x)"
,
where
,
cap
);
dev_info
(
*
ehci
->
hcd
.
controller
,
"BIOS handoff failed (%d, %04x)
\n
"
,
where
,
cap
);
return
1
;
}
dbg
(
"BIOS handoff succeeded"
);
}
else
dbg
(
"BIOS handoff not needed"
);
ehci_dbg
(
ehci
,
"BIOS handoff succeeded
\n
"
);
}
return
0
;
}
...
...
@@ -323,14 +326,15 @@ static int ehci_start (struct usb_hcd *hcd)
u32
cap
;
pci_read_config_dword
(
ehci
->
hcd
.
pdev
,
temp
,
&
cap
);
dbg
(
"capability %04x at %02x
"
,
cap
,
temp
);
ehci_dbg
(
ehci
,
"capability %04x at %02x
\n
"
,
cap
,
temp
);
switch
(
cap
&
0xff
)
{
case
1
:
/* BIOS/SMM/... handoff */
if
(
bios_handoff
(
ehci
,
temp
,
cap
)
!=
0
)
return
-
EOPNOTSUPP
;
break
;
case
0
:
/* illegal reserved capability */
warn
(
"illegal capability!"
);
dev_warn
(
*
ehci
->
hcd
.
controller
,
"illegal capability!
\n
"
);
cap
=
0
;
/* FALLTHROUGH */
default:
/* unknown */
...
...
@@ -360,7 +364,6 @@ static int ehci_start (struct usb_hcd *hcd)
else
// N microframes cached
ehci
->
i_thresh
=
2
+
HCC_ISOC_THRES
(
hcc_params
);
ehci
->
async
=
0
;
ehci
->
reclaim
=
0
;
ehci
->
next_uframe
=
-
1
;
...
...
@@ -374,6 +377,21 @@ static int ehci_start (struct usb_hcd *hcd)
writel
(
INTR_MASK
,
&
ehci
->
regs
->
intr_enable
);
writel
(
ehci
->
periodic_dma
,
&
ehci
->
regs
->
frame_list
);
/*
* dedicate a qh for the async ring head, since we couldn't unlink
* a 'real' qh without stopping the async schedule [4.8]. use it
* as the 'reclamation list head' too.
*/
ehci
->
async
->
qh_next
.
qh
=
0
;
ehci
->
async
->
hw_next
=
QH_NEXT
(
ehci
->
async
->
qh_dma
);
ehci
->
async
->
hw_info1
=
cpu_to_le32
(
QH_HEAD
);
ehci
->
async
->
hw_token
=
cpu_to_le32
(
QTD_STS_HALT
);
ehci
->
async
->
hw_qtd_next
=
EHCI_LIST_END
;
ehci
->
async
->
qh_state
=
QH_STATE_LINKED
;
ehci_qtd_free
(
ehci
,
ehci
->
async
->
dummy
);
ehci
->
async
->
dummy
=
0
;
writel
((
u32
)
ehci
->
async
->
qh_dma
,
&
ehci
->
regs
->
async_next
);
/*
* hcc_params controls whether ehci->regs->segment must (!!!)
* be used; it constrains QH/ITD/SITD and QTD locations.
...
...
@@ -388,7 +406,8 @@ static int ehci_start (struct usb_hcd *hcd)
if
(
HCC_64BIT_ADDR
(
hcc_params
))
{
writel
(
0
,
&
ehci
->
regs
->
segment
);
if
(
!
pci_set_dma_mask
(
ehci
->
hcd
.
pdev
,
0xffffffffffffffffULL
))
info
(
"enabled 64bit PCI DMA (DAC)"
);
dev_info
(
*
ehci
->
hcd
.
controller
,
"enabled 64bit PCI DMA (DAC)
\n
"
);
}
/* clear interrupt enables, set irq latency */
...
...
@@ -435,10 +454,10 @@ static int ehci_start (struct usb_hcd *hcd)
/* PCI Serial Bus Release Number is at 0x60 offset */
pci_read_config_byte
(
hcd
->
pdev
,
0x60
,
&
tempbyte
);
temp
=
readw
(
&
ehci
->
caps
->
hci_version
);
info
(
"USB %x.%x support enabled, EHCI rev %x.%02x, %s %s"
,
((
tempbyte
&
0xf0
)
>>
4
),
(
tempbyte
&
0x0f
)
,
temp
>>
8
,
temp
&
0xff
,
hcd_name
,
DRIVER_VERSION
);
dev_info
(
*
hcd
->
controller
,
"USB %x.%x enabled, EHCI %x.%02x, driver %s
\n
"
,
((
tempbyte
&
0xf0
)
>>
4
),
(
tempbyte
&
0x0f
)
,
temp
>>
8
,
temp
&
0xff
,
DRIVER_VERSION
);
/*
* From here on, khubd concurrently accesses the root
...
...
@@ -470,13 +489,13 @@ static void ehci_stop (struct usb_hcd *hcd)
{
struct
ehci_hcd
*
ehci
=
hcd_to_ehci
(
hcd
);
dbg
(
"%s: stop"
,
hcd_to_bus
(
hcd
)
->
bus_name
);
ehci_dbg
(
ehci
,
"stop
\n
"
);
/* no more interrupts ... */
if
(
hcd
->
state
==
USB_STATE_RUNNING
)
ehci_ready
(
ehci
);
if
(
in_interrupt
())
/* should not happen!! */
err
(
"stopped %s!
"
,
RUN_CONTEXT
);
dev_err
(
*
hcd
->
controller
,
"stopped %s!
\n
"
,
RUN_CONTEXT
);
else
del_timer_sync
(
&
ehci
->
watchdog
);
ehci_reset
(
ehci
);
...
...
@@ -492,9 +511,9 @@ static void ehci_stop (struct usb_hcd *hcd)
ehci_mem_cleanup
(
ehci
);
#ifdef EHCI_STATS
dbg
(
"irq normal %ld err %ld reclaim %ld
"
,
ehci_dbg
(
ehci
,
"irq normal %ld err %ld reclaim %ld
\n
"
,
ehci
->
stats
.
normal
,
ehci
->
stats
.
error
,
ehci
->
stats
.
reclaim
);
dbg
(
"complete %ld unlink %ld
"
,
ehci_dbg
(
ehci
,
"complete %ld unlink %ld
\n
"
,
ehci
->
stats
.
complete
,
ehci
->
stats
.
unlink
);
#endif
...
...
@@ -738,8 +757,8 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
struct
ehci_qh
*
qh
=
(
struct
ehci_qh
*
)
urb
->
hcpriv
;
unsigned
long
flags
;
dbg
(
"%s urb_dequeue %p qh %p state %d
"
,
hcd_to_bus
(
hcd
)
->
bus_name
,
urb
,
qh
,
qh
->
qh_state
);
ehci_vdbg
(
ehci
,
"urb_dequeue %p qh %p state %d
\n
"
,
urb
,
qh
,
qh
->
qh_state
);
switch
(
usb_pipetype
(
urb
->
pipe
))
{
// case PIPE_CONTROL:
...
...
@@ -982,7 +1001,6 @@ MODULE_LICENSE ("GPL");
static
int
__init
init
(
void
)
{
dbg
(
DRIVER_INFO
);
if
(
usb_disabled
())
return
-
ENODEV
;
...
...
drivers/usb/host/ehci-hub.c
View file @
46eb8948
...
...
@@ -40,18 +40,15 @@ static int check_reset_complete (
/* if reset finished and it's still not enabled -- handoff */
if
(
!
(
port_status
&
PORT_PE
))
{
dbg
(
"%s port %d full speed, give to companion, 0x%x"
,
hcd_to_bus
(
&
ehci
->
hcd
)
->
bus_name
,
index
+
1
,
port_status
);
ehci_dbg
(
ehci
,
"port %d full speed --> companion
\n
"
,
index
+
1
);
// what happens if HCS_N_CC(params) == 0 ?
port_status
|=
PORT_OWNER
;
writel
(
port_status
,
&
ehci
->
regs
->
port_status
[
index
]);
}
else
dbg
(
"%s port %d high speed"
,
hcd_to_bus
(
&
ehci
->
hcd
)
->
bus_name
,
index
+
1
);
ehci_dbg
(
ehci
,
"port %d high speed
\n
"
,
index
+
1
);
return
port_status
;
}
...
...
@@ -277,7 +274,7 @@ static int ehci_hub_control (
#ifndef EHCI_VERBOSE_DEBUG
if
(
status
&
~
0xffff
)
/* only if wPortChange is interesting */
#endif
dbg_port
(
hcd
,
"GetStatus"
,
wIndex
+
1
,
temp
);
dbg_port
(
ehci
,
"GetStatus"
,
wIndex
+
1
,
temp
);
// we "know" this alignment is good, caller used kmalloc()...
*
((
u32
*
)
buf
)
=
cpu_to_le32
(
status
);
break
;
...
...
@@ -313,14 +310,12 @@ static int ehci_hub_control (
/* line status bits may report this as low speed */
if
((
temp
&
(
PORT_PE
|
PORT_CONNECT
))
==
PORT_CONNECT
&&
PORT_USB11
(
temp
))
{
dbg
(
"%s port %d low speed, give to companion"
,
hcd_to_bus
(
&
ehci
->
hcd
)
->
bus_name
,
ehci_dbg
(
ehci
,
"port %d low speed --> companion
\n
"
,
wIndex
+
1
);
temp
|=
PORT_OWNER
;
}
else
{
vdbg
(
"%s port %d reset"
,
hcd_to_bus
(
&
ehci
->
hcd
)
->
bus_name
,
wIndex
+
1
);
ehci_vdbg
(
ehci
,
"port %d reset"
,
wIndex
+
1
);
temp
|=
PORT_RESET
;
temp
&=
~
PORT_PE
;
...
...
drivers/usb/host/ehci-mem.c
View file @
46eb8948
...
...
@@ -103,7 +103,7 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
/* dummy td enables safe urb queuing */
qh
->
dummy
=
ehci_qtd_alloc
(
ehci
,
flags
);
if
(
qh
->
dummy
==
0
)
{
dbg
(
"no dummy td
"
);
ehci_dbg
(
ehci
,
"no dummy td
\n
"
);
pci_pool_free
(
ehci
->
qh_pool
,
qh
,
qh
->
qh_dma
);
qh
=
0
;
}
...
...
@@ -113,19 +113,17 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
/* to share a qh (cpu threads, or hc) */
static
inline
struct
ehci_qh
*
qh_get
(
/* ehci, */
struct
ehci_qh
*
qh
)
{
// dbg ("get %p (%d++)", qh, qh->refcount.counter);
atomic_inc
(
&
qh
->
refcount
);
return
qh
;
}
static
void
qh_put
(
struct
ehci_hcd
*
ehci
,
struct
ehci_qh
*
qh
)
{
// dbg ("put %p (--%d)", qh, qh->refcount.counter);
if
(
!
atomic_dec_and_test
(
&
qh
->
refcount
))
return
;
/* clean qtds first, and know this is not linked */
if
(
!
list_empty
(
&
qh
->
qtd_list
)
||
qh
->
qh_next
.
ptr
)
{
dbg
(
"unused qh not empty!
"
);
ehci_dbg
(
ehci
,
"unused qh not empty!
\n
"
);
BUG
();
}
if
(
qh
->
dummy
)
...
...
@@ -142,6 +140,10 @@ static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh)
static
void
ehci_mem_cleanup
(
struct
ehci_hcd
*
ehci
)
{
if
(
ehci
->
async
)
qh_put
(
ehci
,
ehci
->
async
);
ehci
->
async
=
0
;
/* PCI consistent memory and pools */
if
(
ehci
->
qtd_pool
)
pci_pool_destroy
(
ehci
->
qtd_pool
);
...
...
@@ -183,20 +185,20 @@ static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
32
/* byte alignment (for hw parts) */
,
4096
/* can't cross 4K */
);
if
(
!
ehci
->
qtd_pool
)
{
dbg
(
"no qtd pool"
);
ehci_mem_cleanup
(
ehci
);
return
-
ENOMEM
;
goto
fail
;
}
/* QH for control/bulk/intr transfers */
/* QH
s
for control/bulk/intr transfers */
ehci
->
qh_pool
=
pci_pool_create
(
"ehci_qh"
,
ehci
->
hcd
.
pdev
,
sizeof
(
struct
ehci_qh
),
32
/* byte alignment (for hw parts) */
,
4096
/* can't cross 4K */
);
if
(
!
ehci
->
qh_pool
)
{
dbg
(
"no qh pool"
);
ehci_mem_cleanup
(
ehci
);
return
-
ENOMEM
;
goto
fail
;
}
ehci
->
async
=
ehci_qh_alloc
(
ehci
,
flags
);
if
(
!
ehci
->
async
)
{
goto
fail
;
}
/* ITD for high speed ISO transfers */
...
...
@@ -205,9 +207,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
32
/* byte alignment (for hw parts) */
,
4096
/* can't cross 4K */
);
if
(
!
ehci
->
itd_pool
)
{
dbg
(
"no itd pool"
);
ehci_mem_cleanup
(
ehci
);
return
-
ENOMEM
;
goto
fail
;
}
/* SITD for full/low speed split ISO transfers */
...
...
@@ -216,9 +216,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
32
/* byte alignment (for hw parts) */
,
4096
/* can't cross 4K */
);
if
(
!
ehci
->
sitd_pool
)
{
dbg
(
"no sitd pool"
);
ehci_mem_cleanup
(
ehci
);
return
-
ENOMEM
;
goto
fail
;
}
/* Hardware periodic table */
...
...
@@ -227,9 +225,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
ehci
->
periodic_size
*
sizeof
(
u32
),
&
ehci
->
periodic_dma
);
if
(
ehci
->
periodic
==
0
)
{
dbg
(
"no hw periodic table"
);
ehci_mem_cleanup
(
ehci
);
return
-
ENOMEM
;
goto
fail
;
}
for
(
i
=
0
;
i
<
ehci
->
periodic_size
;
i
++
)
ehci
->
periodic
[
i
]
=
EHCI_LIST_END
;
...
...
@@ -237,11 +233,14 @@ static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
/* software shadow of hardware table */
ehci
->
pshadow
=
kmalloc
(
ehci
->
periodic_size
*
sizeof
(
void
*
),
flags
);
if
(
ehci
->
pshadow
==
0
)
{
dbg
(
"no shadow periodic table"
);
ehci_mem_cleanup
(
ehci
);
return
-
ENOMEM
;
goto
fail
;
}
memset
(
ehci
->
pshadow
,
0
,
ehci
->
periodic_size
*
sizeof
(
void
*
));
return
0
;
fail:
ehci_dbg
(
ehci
,
"couldn't init memory
\n
"
);
ehci_mem_cleanup
(
ehci
);
return
-
ENOMEM
;
}
drivers/usb/host/ehci-q.c
View file @
46eb8948
...
...
@@ -130,8 +130,9 @@ static inline void qtd_copy_status (struct urb *urb, size_t length, u32 token)
else
/* unknown */
urb
->
status
=
-
EPROTO
;
dbg
(
"ep %d-%s qtd token %08x --> status %d"
,
/* devpath */
ehci_vdbg
(
ehci
,
"dev%d ep%d%s qtd token %08x --> status %d
\n
"
,
usb_pipedev
(
urb
->
pipe
),
usb_pipeendpoint
(
urb
->
pipe
),
usb_pipein
(
urb
->
pipe
)
?
"in"
:
"out"
,
token
,
urb
->
status
);
...
...
@@ -678,33 +679,33 @@ ehci_qh_make (
static
void
qh_link_async
(
struct
ehci_hcd
*
ehci
,
struct
ehci_qh
*
qh
)
{
u32
dma
=
QH_NEXT
(
qh
->
qh_dma
);
struct
ehci_qh
*
q
;
struct
ehci_qh
*
head
;
if
(
unlikely
(
!
(
q
=
ehci
->
async
)))
{
/* (re)start the async schedule? */
head
=
ehci
->
async
;
if
(
ehci
->
async_idle
)
del_timer
(
&
ehci
->
watchdog
);
else
if
(
!
head
->
qh_next
.
qh
)
{
u32
cmd
=
readl
(
&
ehci
->
regs
->
command
);
/* in case a clear of CMD_ASE didn't take yet */
(
void
)
handshake
(
&
ehci
->
regs
->
status
,
STS_ASS
,
0
,
150
);
qh
->
hw_info1
|=
__constant_cpu_to_le32
(
QH_HEAD
);
/* [4.8] */
qh
->
qh_next
.
qh
=
qh
;
qh
->
hw_next
=
dma
;
wmb
();
ehci
->
async
=
qh
;
writel
((
u32
)
qh
->
qh_dma
,
&
ehci
->
regs
->
async_next
);
cmd
|=
CMD_ASE
|
CMD_RUN
;
writel
(
cmd
,
&
ehci
->
regs
->
command
);
ehci
->
hcd
.
state
=
USB_STATE_RUNNING
;
/* posted write need not be known to HC yet ... */
}
else
{
/* splice right after "start" of ring */
qh
->
hw_info1
&=
~
__constant_cpu_to_le32
(
QH_HEAD
);
/* [4.8] */
qh
->
qh_next
=
q
->
qh_next
;
qh
->
hw_next
=
q
->
hw_next
;
wmb
();
q
->
qh_next
.
qh
=
qh
;
q
->
hw_next
=
dma
;
if
(
!
(
cmd
&
CMD_ASE
))
{
/* in case a clear of CMD_ASE didn't take yet */
(
void
)
handshake
(
&
ehci
->
regs
->
status
,
STS_ASS
,
0
,
150
);
cmd
|=
CMD_ASE
|
CMD_RUN
;
writel
(
cmd
,
&
ehci
->
regs
->
command
);
ehci
->
hcd
.
state
=
USB_STATE_RUNNING
;
/* posted write need not be known to HC yet ... */
}
}
/* splice right after start */
qh
->
qh_next
=
head
->
qh_next
;
qh
->
hw_next
=
head
->
hw_next
;
wmb
();
head
->
qh_next
.
qh
=
qh
;
head
->
hw_next
=
dma
;
qh
->
qh_state
=
QH_STATE_LINKED
;
/* qtd completions reported later by interrupt */
...
...
@@ -897,6 +898,14 @@ static void end_unlink_async (struct ehci_hcd *ehci)
qh_link_async
(
ehci
,
qh
);
else
qh_put
(
ehci
,
qh
);
// refcount from async list
/* it's not free to turn the async schedule on/off, so we leave it
* active but idle for a while once it empties.
*/
if
(
!
ehci
->
async
->
qh_next
.
qh
&&
!
timer_pending
(
&
ehci
->
watchdog
))
{
ehci
->
async_idle
=
1
;
mod_timer
(
&
ehci
->
watchdog
,
jiffies
+
EHCI_ASYNC_JIFFIES
);
}
}
/* makes sure the async qh will become idle */
...
...
@@ -909,7 +918,6 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
#ifdef DEBUG
if
(
ehci
->
reclaim
||
!
ehci
->
async
||
qh
->
qh_state
!=
QH_STATE_LINKED
#ifdef CONFIG_SMP
// this macro lies except on SMP compiles
...
...
@@ -919,31 +927,20 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
BUG
();
#endif
qh
->
qh_state
=
QH_STATE_UNLINK
;
ehci
->
reclaim
=
qh
=
qh_get
(
qh
);
// dbg_qh ("start unlink", ehci, qh);
/* Remove the last QH (qhead)? Stop async schedule first. */
if
(
unlikely
(
qh
==
ehci
->
async
&&
qh
->
qh_next
.
qh
==
qh
))
{
/* stop async schedule right now? */
if
(
unlikely
(
qh
==
ehci
->
async
))
{
/* can't get here without STS_ASS set */
if
(
ehci
->
hcd
.
state
!=
USB_STATE_HALT
)
{
writel
(
cmd
&
~
CMD_ASE
,
&
ehci
->
regs
->
command
);
(
void
)
handshake
(
&
ehci
->
regs
->
status
,
STS_ASS
,
0
,
150
);
#if 0
// one VT8235 system wants to die with STS_FATAL
// unless this qh is leaked here. others seem ok...
qh = qh_get (qh);
dbg_qh ("async/off", ehci, qh);
#endif
wmb
();
// handshake later, if we need to
}
qh
->
qh_next
.
qh
=
ehci
->
async
=
0
;
ehci
->
reclaim_ready
=
1
;
tasklet_schedule
(
&
ehci
->
tasklet
);
return
;
}
qh
->
qh_state
=
QH_STATE_UNLINK
;
ehci
->
reclaim
=
qh
=
qh_get
(
qh
);
if
(
unlikely
(
ehci
->
hcd
.
state
==
USB_STATE_HALT
))
{
ehci
->
reclaim_ready
=
1
;
tasklet_schedule
(
&
ehci
->
tasklet
);
...
...
@@ -951,13 +948,9 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
}
prev
=
ehci
->
async
;
while
(
prev
->
qh_next
.
qh
!=
qh
&&
prev
->
qh_next
.
qh
!=
ehci
->
async
)
while
(
prev
->
qh_next
.
qh
!=
qh
)
prev
=
prev
->
qh_next
.
qh
;
if
(
qh
->
hw_info1
&
__constant_cpu_to_le32
(
QH_HEAD
))
{
ehci
->
async
=
prev
;
prev
->
hw_info1
|=
__constant_cpu_to_le32
(
QH_HEAD
);
}
prev
->
hw_next
=
qh
->
hw_next
;
prev
->
qh_next
=
qh
->
qh_next
;
wmb
();
...
...
@@ -979,7 +972,7 @@ scan_async (struct ehci_hcd *ehci)
unsigned
count
;
rescan:
qh
=
ehci
->
async
;
qh
=
ehci
->
async
->
qh_next
.
qh
;
count
=
0
;
if
(
likely
(
qh
!=
0
))
{
do
{
...
...
@@ -991,25 +984,17 @@ scan_async (struct ehci_hcd *ehci)
/* concurrent unlink could happen here */
count
+=
qh_completions
(
ehci
,
qh
);
qh_put
(
ehci
,
qh
);
goto
rescan
;
}
/* unlink idle entries, reducing HC PCI usage as
* well as HCD schedule-scanning costs. removing
* the last qh is deferred, since it's costly.
* well as HCD schedule-scanning costs.
*
* FIXME don't unlink idle entries so quickly; it
* can penalize (common) half duplex protocols.
*/
if
(
list_empty
(
&
qh
->
qtd_list
)
&&
!
ehci
->
reclaim
)
{
if
(
qh
->
qh_next
.
qh
!=
qh
)
{
// dbg ("irq/empty");
start_unlink_async
(
ehci
,
qh
);
}
else
if
(
!
timer_pending
(
&
ehci
->
watchdog
))
{
/* can't use IAA for last entry */
ehci
->
async_idle
=
1
;
mod_timer
(
&
ehci
->
watchdog
,
jiffies
+
EHCI_ASYNC_JIFFIES
);
}
start_unlink_async
(
ehci
,
qh
);
}
/* keep latencies down: let any irqs in */
...
...
@@ -1021,8 +1006,6 @@ scan_async (struct ehci_hcd *ehci)
}
qh
=
qh
->
qh_next
.
qh
;
if
(
!
qh
)
/* unlinked? */
goto
rescan
;
}
while
(
qh
!=
ehci
->
async
);
}
while
(
qh
);
}
}
drivers/usb/host/uhci-hcd.c
View file @
46eb8948
...
...
@@ -1051,10 +1051,6 @@ static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb)
td_error:
ret
=
uhci_map_status
(
status
,
uhci_packetout
(
td_token
(
td
)));
if
(
ret
==
-
EPIPE
)
/* endpoint has stalled - mark it halted */
usb_endpoint_halt
(
urb
->
dev
,
uhci_endpoint
(
td_token
(
td
)),
uhci_packetout
(
td_token
(
td
)));
err:
if
((
debug
==
1
&&
ret
!=
-
EPIPE
)
||
debug
>
1
)
{
...
...
drivers/usb/serial/usb-serial.c
View file @
46eb8948
...
...
@@ -467,9 +467,12 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
down
(
&
port
->
sem
);
port
->
tty
=
tty
;
/* lock this module before we call it */
if
(
serial
->
type
->
owner
)
__MOD_INC_USE_COUNT
(
serial
->
type
->
owner
);
/* lock this module before we call it,
this may, which means we must bail out, safe because we are called with BKL held */
if
(
!
try_module_get
(
serial
->
type
->
owner
))
{
retval
=
-
ENODEV
;
goto
bailout
;
}
++
port
->
open_count
;
if
(
port
->
open_count
==
1
)
{
...
...
@@ -481,10 +484,10 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
retval
=
usb_serial_generic_open
(
port
,
filp
);
if
(
retval
)
{
port
->
open_count
=
0
;
if
(
serial
->
type
->
owner
)
__MOD_DEC_USE_COUNT
(
serial
->
type
->
owner
);
module_put
(
serial
->
type
->
owner
);
}
}
bailout:
up
(
&
port
->
sem
);
return
retval
;
...
...
@@ -508,8 +511,7 @@ static void __serial_close(struct usb_serial_port *port, struct file *filp)
port
->
open_count
=
0
;
}
if
(
port
->
serial
->
type
->
owner
)
__MOD_DEC_USE_COUNT
(
port
->
serial
->
type
->
owner
);
module_put
(
port
->
serial
->
type
->
owner
);
}
static
void
serial_close
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
...
...
@@ -899,11 +901,13 @@ int usb_serial_probe(struct usb_interface *interface,
/* if this device type has a probe function, call it */
if
(
type
->
probe
)
{
if
(
type
->
owner
)
__MOD_INC_USE_COUNT
(
type
->
owner
);
if
(
!
try_module_get
(
type
->
owner
))
{
err
(
"module get failed, exiting"
);
kfree
(
serial
);
return
-
EIO
;
}
retval
=
type
->
probe
(
serial
);
if
(
type
->
owner
)
__MOD_DEC_USE_COUNT
(
type
->
owner
);
module_put
(
type
->
owner
);
if
(
retval
<
0
)
{
dbg
(
"sub driver rejected device"
);
...
...
@@ -996,11 +1000,13 @@ int usb_serial_probe(struct usb_interface *interface,
if
(
!
num_ports
)
{
/* if this device type has a calc_num_ports function, call it */
if
(
type
->
calc_num_ports
)
{
if
(
type
->
owner
)
__MOD_INC_USE_COUNT
(
type
->
owner
);
if
(
!
try_module_get
(
type
->
owner
))
{
err
(
"module get failed, exiting"
);
kfree
(
serial
);
return
-
EIO
;
}
num_ports
=
type
->
calc_num_ports
(
serial
);
if
(
type
->
owner
)
__MOD_DEC_USE_COUNT
(
type
->
owner
);
module_put
(
type
->
owner
);
}
if
(
!
num_ports
)
num_ports
=
type
->
num_ports
;
...
...
@@ -1110,11 +1116,12 @@ int usb_serial_probe(struct usb_interface *interface,
/* if this device type has an attach function, call it */
if
(
type
->
attach
)
{
if
(
type
->
owner
)
__MOD_INC_USE_COUNT
(
type
->
owner
);
if
(
!
try_module_get
(
type
->
owner
))
{
err
(
"module get failed, exiting"
);
goto
probe_error
;
}
retval
=
type
->
attach
(
serial
);
if
(
type
->
owner
)
__MOD_DEC_USE_COUNT
(
type
->
owner
);
module_put
(
type
->
owner
);
if
(
retval
<
0
)
goto
probe_error
;
if
(
retval
>
0
)
{
...
...
drivers/usb/storage/transport.c
View file @
46eb8948
...
...
@@ -532,8 +532,6 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
if
(
result
<
0
)
return
result
;
printk
(
KERN_ERR
"usb_stor_clear_halt() WORKED!
\n
"
);
/* reset the toggles and endpoint flags */
usb_endpoint_running
(
us
->
pusb_dev
,
usb_pipeendpoint
(
pipe
),
usb_pipeout
(
pipe
));
...
...
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