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
5bcd0bb6
Commit
5bcd0bb6
authored
Jun 15, 2003
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Plain Diff
Merge kroah.com:/home/greg/linux/BK/bleed-2.5
into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents
4fb416f4
6332c743
Changes
23
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
366 additions
and
265 deletions
+366
-265
Documentation/usb/dma.txt
Documentation/usb/dma.txt
+22
-10
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-acm.c
+95
-92
drivers/usb/class/usblp.c
drivers/usb/class/usblp.c
+11
-11
drivers/usb/core/hcd.c
drivers/usb/core/hcd.c
+16
-12
drivers/usb/core/hub.c
drivers/usb/core/hub.c
+1
-1
drivers/usb/core/message.c
drivers/usb/core/message.c
+2
-1
drivers/usb/core/urb.c
drivers/usb/core/urb.c
+1
-1
drivers/usb/core/usb.c
drivers/usb/core/usb.c
+37
-19
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-dbg.c
+31
-17
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hcd.c
+6
-8
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-q.c
+23
-21
drivers/usb/host/ehci.h
drivers/usb/host/ehci.h
+4
-1
drivers/usb/input/aiptek.c
drivers/usb/input/aiptek.c
+1
-1
drivers/usb/input/hid-core.c
drivers/usb/input/hid-core.c
+4
-3
drivers/usb/input/kbtab.c
drivers/usb/input/kbtab.c
+1
-1
drivers/usb/input/powermate.c
drivers/usb/input/powermate.c
+2
-2
drivers/usb/input/usbkbd.c
drivers/usb/input/usbkbd.c
+3
-2
drivers/usb/input/usbmouse.c
drivers/usb/input/usbmouse.c
+1
-1
drivers/usb/input/wacom.c
drivers/usb/input/wacom.c
+1
-1
drivers/usb/input/xpad.c
drivers/usb/input/xpad.c
+1
-1
drivers/usb/misc/speedtch.c
drivers/usb/misc/speedtch.c
+73
-36
drivers/usb/misc/usbtest.c
drivers/usb/misc/usbtest.c
+1
-1
include/linux/usb.h
include/linux/usb.h
+29
-22
No files found.
Documentation/usb/dma.txt
View file @
5bcd0bb6
...
@@ -15,10 +15,12 @@ OR: they can now be DMA-aware.
...
@@ -15,10 +15,12 @@ OR: they can now be DMA-aware.
manage dma mappings for existing dma-ready buffers (see below).
manage dma mappings for existing dma-ready buffers (see below).
- URBs have an additional "transfer_dma" field, as well as a transfer_flags
- URBs have an additional "transfer_dma" field, as well as a transfer_flags
bit saying if it's valid. (Control requests also needed "setup_dma".)
bit saying if it's valid. (Control requests also have "setup_dma" and a
corresponding transfer_flags bit.)
- "usbcore" will map those DMA addresses, if a DMA-aware driver didn't do it
- "usbcore" will map those DMA addresses, if a DMA-aware driver didn't do
first and set URB_NO_DMA_MAP. HCDs don't manage dma mappings for urbs.
it first and set URB_NO_TRANSFER_DMA_MAP or URB_NO_SETUP_DMA_MAP. HCDs
don't manage dma mappings for URBs.
- There's a new "generic DMA API", parts of which are usable by USB device
- There's a new "generic DMA API", parts of which are usable by USB device
drivers. Never use dma_set_mask() on any USB interface or device; that
drivers. Never use dma_set_mask() on any USB interface or device; that
...
@@ -33,8 +35,9 @@ and effects like cache-trashing can impose subtle penalties.
...
@@ -33,8 +35,9 @@ and effects like cache-trashing can impose subtle penalties.
- When you're allocating a buffer for DMA purposes anyway, use the buffer
- When you're allocating a buffer for DMA purposes anyway, use the buffer
primitives. Think of them as kmalloc and kfree that give you the right
primitives. Think of them as kmalloc and kfree that give you the right
kind of addresses to store in urb->transfer_buffer and urb->transfer_dma,
kind of addresses to store in urb->transfer_buffer and urb->transfer_dma,
while guaranteeing that hidden copies through DMA "bounce" buffers won't
while guaranteeing that no hidden copies through DMA "bounce" buffers will
slow things down. You'd also set URB_NO_DMA_MAP in urb->transfer_flags:
slow things down. You'd also set URB_NO_TRANSFER_DMA_MAP in
urb->transfer_flags:
void *usb_buffer_alloc (struct usb_device *dev, size_t size,
void *usb_buffer_alloc (struct usb_device *dev, size_t size,
int mem_flags, dma_addr_t *dma);
int mem_flags, dma_addr_t *dma);
...
@@ -42,10 +45,18 @@ and effects like cache-trashing can impose subtle penalties.
...
@@ -42,10 +45,18 @@ and effects like cache-trashing can impose subtle penalties.
void usb_buffer_free (struct usb_device *dev, size_t size,
void usb_buffer_free (struct usb_device *dev, size_t size,
void *addr, dma_addr_t dma);
void *addr, dma_addr_t dma);
For control transfers you can use the buffer primitives or not for each
of the transfer buffer and setup buffer independently. Set the flag bits
URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP to indicate which
buffers you have prepared. For non-control transfers URB_NO_SETUP_DMA_MAP
is ignored.
The memory buffer returned is "dma-coherent"; sometimes you might need to
The memory buffer returned is "dma-coherent"; sometimes you might need to
force a consistent memory access ordering by using memory barriers. It's
force a consistent memory access ordering by using memory barriers. It's
not using a streaming DMA mapping, so it's good for small transfers on
not using a streaming DMA mapping, so it's good for small transfers on
systems where the I/O would otherwise tie up an IOMMU mapping.
systems where the I/O would otherwise tie up an IOMMU mapping. (See
Documentation/DMA-mapping.txt for definitions of "coherent" and "streaming"
DMA mappings.)
Asking for 1/Nth of a page (as well as asking for N pages) is reasonably
Asking for 1/Nth of a page (as well as asking for N pages) is reasonably
space-efficient.
space-efficient.
...
@@ -91,7 +102,8 @@ DMA address space of the device.
...
@@ -91,7 +102,8 @@ DMA address space of the device.
These calls all work with initialized urbs: urb->dev, urb->pipe,
These calls all work with initialized urbs: urb->dev, urb->pipe,
urb->transfer_buffer, and urb->transfer_buffer_length must all be
urb->transfer_buffer, and urb->transfer_buffer_length must all be
valid when these calls are used:
valid when these calls are used (urb->setup_packet must be valid too
if urb is a control request):
struct urb *usb_buffer_map (struct urb *urb);
struct urb *usb_buffer_map (struct urb *urb);
...
@@ -99,6 +111,6 @@ DMA address space of the device.
...
@@ -99,6 +111,6 @@ DMA address space of the device.
void usb_buffer_unmap (struct urb *urb);
void usb_buffer_unmap (struct urb *urb);
The calls manage urb->transfer_dma for you, and set URB_NO_
DMA_MAP so that
The calls manage urb->transfer_dma for you, and set URB_NO_
TRANSFER_DMA_MAP
usbcore won't map or unmap the buffer.
so that usbcore won't map or unmap the buffer. The same goes for
urb->setup_dma and URB_NO_SETUP_DMA_MAP for control requests.
drivers/usb/class/cdc-acm.c
View file @
5bcd0bb6
...
@@ -548,7 +548,7 @@ static int acm_probe (struct usb_interface *intf,
...
@@ -548,7 +548,7 @@ static int acm_probe (struct usb_interface *intf,
struct
usb_host_config
*
cfacm
;
struct
usb_host_config
*
cfacm
;
struct
usb_host_interface
*
ifcom
,
*
ifdata
;
struct
usb_host_interface
*
ifcom
,
*
ifdata
;
struct
usb_endpoint_descriptor
*
epctrl
,
*
epread
,
*
epwrite
;
struct
usb_endpoint_descriptor
*
epctrl
,
*
epread
,
*
epwrite
;
int
readsize
,
ctrlsize
,
minor
,
i
;
int
readsize
,
ctrlsize
,
minor
,
i
,
j
;
unsigned
char
*
buf
;
unsigned
char
*
buf
;
dev
=
interface_to_usbdev
(
intf
);
dev
=
interface_to_usbdev
(
intf
);
...
@@ -558,23 +558,25 @@ static int acm_probe (struct usb_interface *intf,
...
@@ -558,23 +558,25 @@ static int acm_probe (struct usb_interface *intf,
dbg
(
"probing config %d"
,
cfacm
->
desc
.
bConfigurationValue
);
dbg
(
"probing config %d"
,
cfacm
->
desc
.
bConfigurationValue
);
if
(
cfacm
->
desc
.
bNumInterfaces
!=
2
||
for
(
j
=
0
;
j
<
cfacm
->
desc
.
bNumInterfaces
-
1
;
j
++
)
{
usb_interface_claimed
(
cfacm
->
interface
+
0
)
||
usb_interface_claimed
(
cfacm
->
interface
+
1
))
if
(
usb_interface_claimed
(
cfacm
->
interface
+
j
)
||
usb_interface_claimed
(
cfacm
->
interface
+
j
+
1
))
continue
;
continue
;
ifcom
=
cfacm
->
interface
[
0
].
altsetting
+
0
;
ifcom
=
cfacm
->
interface
[
j
].
altsetting
+
0
;
ifdata
=
cfacm
->
interface
[
1
].
altsetting
+
0
;
ifdata
=
cfacm
->
interface
[
j
+
1
].
altsetting
+
0
;
if
(
ifdata
->
desc
.
bInterfaceClass
!=
10
||
ifdata
->
desc
.
bNumEndpoints
<
2
)
{
if
(
ifdata
->
desc
.
bInterfaceClass
!=
10
||
ifdata
->
desc
.
bNumEndpoints
<
2
)
{
ifcom
=
cfacm
->
interface
[
1
].
altsetting
+
0
;
ifcom
=
cfacm
->
interface
[
j
+
1
].
altsetting
+
0
;
ifdata
=
cfacm
->
interface
[
0
].
altsetting
+
0
;
ifdata
=
cfacm
->
interface
[
j
].
altsetting
+
0
;
if
(
ifdata
->
desc
.
bInterfaceClass
!=
10
||
ifdata
->
desc
.
bNumEndpoints
<
2
)
if
(
ifdata
->
desc
.
bInterfaceClass
!=
10
||
ifdata
->
desc
.
bNumEndpoints
<
2
)
continue
;
continue
;
}
}
if
(
ifcom
->
desc
.
bInterfaceClass
!=
2
||
ifcom
->
desc
.
bInterfaceSubClass
!=
2
||
if
(
ifcom
->
desc
.
bInterfaceClass
!=
2
||
ifcom
->
desc
.
bInterfaceSubClass
!=
2
||
ifcom
->
desc
.
bInterfaceProtocol
!=
1
||
ifcom
->
desc
.
bNumEndpoints
<
1
)
ifcom
->
desc
.
bInterfaceProtocol
<
1
||
ifcom
->
desc
.
bInterfaceProtocol
>
6
||
ifcom
->
desc
.
bNumEndpoints
<
1
)
continue
;
continue
;
epctrl
=
&
ifcom
->
endpoint
[
0
].
desc
;
epctrl
=
&
ifcom
->
endpoint
[
0
].
desc
;
...
@@ -608,7 +610,7 @@ static int acm_probe (struct usb_interface *intf,
...
@@ -608,7 +610,7 @@ static int acm_probe (struct usb_interface *intf,
ctrlsize
=
epctrl
->
wMaxPacketSize
;
ctrlsize
=
epctrl
->
wMaxPacketSize
;
readsize
=
epread
->
wMaxPacketSize
;
readsize
=
epread
->
wMaxPacketSize
;
acm
->
writesize
=
epwrite
->
wMaxPacketSize
;
acm
->
writesize
=
epwrite
->
wMaxPacketSize
;
acm
->
iface
=
cfacm
->
interface
;
acm
->
iface
=
cfacm
->
interface
+
j
;
acm
->
minor
=
minor
;
acm
->
minor
=
minor
;
acm
->
dev
=
dev
;
acm
->
dev
=
dev
;
...
@@ -673,6 +675,7 @@ static int acm_probe (struct usb_interface *intf,
...
@@ -673,6 +675,7 @@ static int acm_probe (struct usb_interface *intf,
usb_set_intfdata
(
intf
,
acm
);
usb_set_intfdata
(
intf
,
acm
);
return
0
;
return
0
;
}
}
}
return
-
EIO
;
return
-
EIO
;
}
}
...
...
drivers/usb/class/usblp.c
View file @
5bcd0bb6
...
@@ -296,13 +296,13 @@ static int usblp_check_status(struct usblp *usblp, int err)
...
@@ -296,13 +296,13 @@ static int usblp_check_status(struct usblp *usblp, int err)
}
}
status
=
*
usblp
->
statusbuf
;
status
=
*
usblp
->
statusbuf
;
if
(
~
status
&
LP_PERRORP
)
{
if
(
~
status
&
LP_PERRORP
)
newerr
=
3
;
newerr
=
3
;
if
(
status
&
LP_POUTPA
)
if
(
status
&
LP_POUTPA
)
newerr
=
1
;
newerr
=
1
;
if
(
~
status
&
LP_PSELECD
)
if
(
~
status
&
LP_PSELECD
)
newerr
=
2
;
newerr
=
2
;
}
if
(
newerr
!=
err
)
if
(
newerr
!=
err
)
info
(
"usblp%d: %s"
,
usblp
->
minor
,
usblp_messages
[
newerr
]);
info
(
"usblp%d: %s"
,
usblp
->
minor
,
usblp_messages
[
newerr
]);
...
@@ -426,7 +426,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
...
@@ -426,7 +426,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
{
{
struct
usblp
*
usblp
=
file
->
private_data
;
struct
usblp
*
usblp
=
file
->
private_data
;
int
length
,
err
,
i
;
int
length
,
err
,
i
;
unsigned
char
lpstatus
,
newChannel
;
unsigned
char
newChannel
;
int
status
;
int
status
;
int
twoints
[
2
];
int
twoints
[
2
];
int
retval
=
0
;
int
retval
=
0
;
...
@@ -578,12 +578,12 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
...
@@ -578,12 +578,12 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch
(
cmd
)
{
switch
(
cmd
)
{
case
LPGETSTATUS
:
case
LPGETSTATUS
:
if
(
usblp_read_status
(
usblp
,
&
lpstatus
))
{
if
(
usblp_read_status
(
usblp
,
usblp
->
statusbuf
))
{
err
(
"usblp%d: failed reading printer status"
,
usblp
->
minor
);
err
(
"usblp%d: failed reading printer status"
,
usblp
->
minor
);
retval
=
-
EIO
;
retval
=
-
EIO
;
goto
done
;
goto
done
;
}
}
status
=
lpstatus
;
status
=
*
usblp
->
statusbuf
;
if
(
copy_to_user
((
int
*
)
arg
,
&
status
,
sizeof
(
int
)))
if
(
copy_to_user
((
int
*
)
arg
,
&
status
,
sizeof
(
int
)))
retval
=
-
EFAULT
;
retval
=
-
EFAULT
;
break
;
break
;
...
@@ -858,8 +858,8 @@ static int usblp_probe(struct usb_interface *intf,
...
@@ -858,8 +858,8 @@ static int usblp_probe(struct usb_interface *intf,
}
}
usblp
->
writebuf
=
usblp
->
readbuf
=
NULL
;
usblp
->
writebuf
=
usblp
->
readbuf
=
NULL
;
usblp
->
writeurb
->
transfer_flags
=
URB_NO_DMA_MAP
;
usblp
->
writeurb
->
transfer_flags
=
URB_NO_
TRANSFER_
DMA_MAP
;
usblp
->
readurb
->
transfer_flags
=
URB_NO_DMA_MAP
;
usblp
->
readurb
->
transfer_flags
=
URB_NO_
TRANSFER_
DMA_MAP
;
/* Malloc write & read buffers. We somewhat wastefully
/* Malloc write & read buffers. We somewhat wastefully
* malloc both regardless of bidirectionality, because the
* malloc both regardless of bidirectionality, because the
* alternate setting can be changed later via an ioctl. */
* alternate setting can be changed later via an ioctl. */
...
...
drivers/usb/core/hcd.c
View file @
5bcd0bb6
...
@@ -459,7 +459,8 @@ static int rh_status_urb (struct usb_hcd *hcd, struct urb *urb)
...
@@ -459,7 +459,8 @@ static int rh_status_urb (struct usb_hcd *hcd, struct urb *urb)
/* rh_timer protected by hcd_data_lock */
/* rh_timer protected by hcd_data_lock */
if
(
hcd
->
rh_timer
.
data
if
(
hcd
->
rh_timer
.
data
||
urb
->
status
!=
-
EINPROGRESS
||
urb
->
status
!=
-
EINPROGRESS
||
urb
->
transfer_buffer_length
<
len
)
{
||
urb
->
transfer_buffer_length
<
len
||
!
HCD_IS_RUNNING
(
hcd
->
state
))
{
dev_dbg
(
hcd
->
controller
,
dev_dbg
(
hcd
->
controller
,
"not queuing rh status urb, stat %d
\n
"
,
"not queuing rh status urb, stat %d
\n
"
,
urb
->
status
);
urb
->
status
);
...
@@ -489,11 +490,10 @@ static void rh_report_status (unsigned long ptr)
...
@@ -489,11 +490,10 @@ static void rh_report_status (unsigned long ptr)
local_irq_save
(
flags
);
local_irq_save
(
flags
);
spin_lock
(
&
urb
->
lock
);
spin_lock
(
&
urb
->
lock
);
/* do nothing if the
hc is gone or the
urb's been unlinked */
/* do nothing if the urb's been unlinked */
if
(
!
urb
->
dev
if
(
!
urb
->
dev
||
urb
->
status
!=
-
EINPROGRESS
||
urb
->
status
!=
-
EINPROGRESS
||
(
hcd
=
urb
->
dev
->
bus
->
hcpriv
)
==
0
||
(
hcd
=
urb
->
dev
->
bus
->
hcpriv
)
==
0
)
{
||
!
HCD_IS_RUNNING
(
hcd
->
state
))
{
spin_unlock
(
&
urb
->
lock
);
spin_unlock
(
&
urb
->
lock
);
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
return
;
return
;
...
@@ -1027,7 +1027,8 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
...
@@ -1027,7 +1027,8 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
* valid and usb_buffer_{sync,unmap}() not be needed, since
* valid and usb_buffer_{sync,unmap}() not be needed, since
* they could clobber root hub response data.
* they could clobber root hub response data.
*/
*/
urb
->
transfer_flags
|=
URB_NO_DMA_MAP
;
urb
->
transfer_flags
|=
(
URB_NO_TRANSFER_DMA_MAP
|
URB_NO_SETUP_DMA_MAP
);
status
=
rh_urb_enqueue
(
hcd
,
urb
);
status
=
rh_urb_enqueue
(
hcd
,
urb
);
goto
done
;
goto
done
;
}
}
...
@@ -1035,15 +1036,16 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
...
@@ -1035,15 +1036,16 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
/* lower level hcd code should use *_dma exclusively,
/* lower level hcd code should use *_dma exclusively,
* unless it uses pio or talks to another transport.
* unless it uses pio or talks to another transport.
*/
*/
if
(
!
(
urb
->
transfer_flags
&
URB_NO_DMA_MAP
)
if
(
hcd
->
controller
->
dma_mask
)
{
&&
hcd
->
controller
->
dma_mask
)
{
if
(
usb_pipecontrol
(
urb
->
pipe
)
if
(
usb_pipecontrol
(
urb
->
pipe
))
&&
!
(
urb
->
transfer_flags
&
URB_NO_SETUP_DMA_MAP
))
urb
->
setup_dma
=
dma_map_single
(
urb
->
setup_dma
=
dma_map_single
(
hcd
->
controller
,
hcd
->
controller
,
urb
->
setup_packet
,
urb
->
setup_packet
,
sizeof
(
struct
usb_ctrlrequest
),
sizeof
(
struct
usb_ctrlrequest
),
DMA_TO_DEVICE
);
DMA_TO_DEVICE
);
if
(
urb
->
transfer_buffer_length
!=
0
)
if
(
urb
->
transfer_buffer_length
!=
0
&&
!
(
urb
->
transfer_flags
&
URB_NO_TRANSFER_DMA_MAP
))
urb
->
transfer_dma
=
dma_map_single
(
urb
->
transfer_dma
=
dma_map_single
(
hcd
->
controller
,
hcd
->
controller
,
urb
->
transfer_buffer
,
urb
->
transfer_buffer
,
...
@@ -1410,12 +1412,14 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs
...
@@ -1410,12 +1412,14 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs
// It would catch exit/unlink paths for all urbs.
// It would catch exit/unlink paths for all urbs.
/* lower level hcd code should use *_dma exclusively */
/* lower level hcd code should use *_dma exclusively */
if
(
!
(
urb
->
transfer_flags
&
URB_NO_DMA_MAP
))
{
if
(
hcd
->
controller
->
dma_mask
)
{
if
(
usb_pipecontrol
(
urb
->
pipe
))
if
(
usb_pipecontrol
(
urb
->
pipe
)
&&
!
(
urb
->
transfer_flags
&
URB_NO_SETUP_DMA_MAP
))
pci_unmap_single
(
hcd
->
pdev
,
urb
->
setup_dma
,
pci_unmap_single
(
hcd
->
pdev
,
urb
->
setup_dma
,
sizeof
(
struct
usb_ctrlrequest
),
sizeof
(
struct
usb_ctrlrequest
),
PCI_DMA_TODEVICE
);
PCI_DMA_TODEVICE
);
if
(
urb
->
transfer_buffer_length
!=
0
)
if
(
urb
->
transfer_buffer_length
!=
0
&&
!
(
urb
->
transfer_flags
&
URB_NO_TRANSFER_DMA_MAP
))
pci_unmap_single
(
hcd
->
pdev
,
urb
->
transfer_dma
,
pci_unmap_single
(
hcd
->
pdev
,
urb
->
transfer_dma
,
urb
->
transfer_buffer_length
,
urb
->
transfer_buffer_length
,
usb_pipein
(
urb
->
pipe
)
usb_pipein
(
urb
->
pipe
)
...
...
drivers/usb/core/hub.c
View file @
5bcd0bb6
...
@@ -461,7 +461,7 @@ static int hub_configure(struct usb_hub *hub,
...
@@ -461,7 +461,7 @@ static int hub_configure(struct usb_hub *hub,
usb_fill_int_urb
(
hub
->
urb
,
dev
,
pipe
,
*
hub
->
buffer
,
maxp
,
hub_irq
,
usb_fill_int_urb
(
hub
->
urb
,
dev
,
pipe
,
*
hub
->
buffer
,
maxp
,
hub_irq
,
hub
,
endpoint
->
bInterval
);
hub
,
endpoint
->
bInterval
);
hub
->
urb
->
transfer_dma
=
hub
->
buffer_dma
;
hub
->
urb
->
transfer_dma
=
hub
->
buffer_dma
;
hub
->
urb
->
transfer_flags
|=
URB_NO_DMA_MAP
;
hub
->
urb
->
transfer_flags
|=
URB_NO_
TRANSFER_
DMA_MAP
;
ret
=
usb_submit_urb
(
hub
->
urb
,
GFP_KERNEL
);
ret
=
usb_submit_urb
(
hub
->
urb
,
GFP_KERNEL
);
if
(
ret
)
{
if
(
ret
)
{
message
=
"couldn't submit status urb"
;
message
=
"couldn't submit status urb"
;
...
...
drivers/usb/core/message.c
View file @
5bcd0bb6
...
@@ -344,7 +344,8 @@ int usb_sg_init (
...
@@ -344,7 +344,8 @@ int usb_sg_init (
if
(
!
io
->
urbs
)
if
(
!
io
->
urbs
)
goto
nomem
;
goto
nomem
;
urb_flags
=
URB_ASYNC_UNLINK
|
URB_NO_DMA_MAP
|
URB_NO_INTERRUPT
;
urb_flags
=
URB_ASYNC_UNLINK
|
URB_NO_TRANSFER_DMA_MAP
|
URB_NO_INTERRUPT
;
if
(
usb_pipein
(
pipe
))
if
(
usb_pipein
(
pipe
))
urb_flags
|=
URB_SHORT_NOT_OK
;
urb_flags
|=
URB_SHORT_NOT_OK
;
...
...
drivers/usb/core/urb.c
View file @
5bcd0bb6
...
@@ -297,7 +297,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
...
@@ -297,7 +297,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
/* enforce simple/standard policy */
/* enforce simple/standard policy */
allowed
=
URB_ASYNC_UNLINK
;
// affects later unlinks
allowed
=
URB_ASYNC_UNLINK
;
// affects later unlinks
allowed
|=
URB_NO_DMA_MAP
;
allowed
|=
(
URB_NO_TRANSFER_DMA_MAP
|
URB_NO_SETUP_DMA_MAP
)
;
allowed
|=
URB_NO_INTERRUPT
;
allowed
|=
URB_NO_INTERRUPT
;
switch
(
temp
)
{
switch
(
temp
)
{
case
PIPE_BULK
:
case
PIPE_BULK
:
...
...
drivers/usb/core/usb.c
View file @
5bcd0bb6
...
@@ -1234,7 +1234,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
...
@@ -1234,7 +1234,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
}
}
/**
/**
* usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_DMA_MAP
* usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_
xxx_
DMA_MAP
* @dev: device the buffer will be used with
* @dev: device the buffer will be used with
* @size: requested buffer size
* @size: requested buffer size
* @mem_flags: affect whether allocation may block
* @mem_flags: affect whether allocation may block
...
@@ -1245,9 +1245,9 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
...
@@ -1245,9 +1245,9 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
* specified device. Such cpu-space buffers are returned along with the DMA
* specified device. Such cpu-space buffers are returned along with the DMA
* address (through the pointer provided).
* address (through the pointer provided).
*
*
* These buffers are used with URB_NO_
DMA_MAP set in urb->transfer_flags to
* These buffers are used with URB_NO_
xxx_DMA_MAP set in urb->transfer_flags
*
avoid behaviors like using "DMA bounce buffers", or tying down I/O mapping
*
to avoid behaviors like using "DMA bounce buffers", or tying down I/O
* hardware for long idle periods. The implementation varies between
*
mapping
hardware for long idle periods. The implementation varies between
* platforms, depending on details of how DMA will work to this device.
* platforms, depending on details of how DMA will work to this device.
* Using these buffers also helps prevent cacheline sharing problems on
* Using these buffers also helps prevent cacheline sharing problems on
* architectures where CPU caches are not DMA-coherent.
* architectures where CPU caches are not DMA-coherent.
...
@@ -1291,17 +1291,17 @@ void usb_buffer_free (
...
@@ -1291,17 +1291,17 @@ void usb_buffer_free (
/**
/**
* usb_buffer_map - create DMA mapping(s) for an urb
* usb_buffer_map - create DMA mapping(s) for an urb
* @urb: urb whose transfer_buffer will be mapped
* @urb: urb whose transfer_buffer
/setup_packet
will be mapped
*
*
* Return value is either null (indicating no buffer could be mapped), or
* Return value is either null (indicating no buffer could be mapped), or
* the parameter. URB_NO_DMA_MAP is added to urb->transfer_flags if the
* the parameter. URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP are
* operation succeeds. If the device is connected to this system through
* added to urb->transfer_flags if the operation succeeds. If the device
* a non-DMA controller, this operation always succeeds.
* is connected to this system through a non-DMA controller, this operation
* always succeeds.
*
*
* This call would normally be used for an urb which is reused, perhaps
* This call would normally be used for an urb which is reused, perhaps
* as the target of a large periodic transfer, with usb_buffer_dmasync()
* as the target of a large periodic transfer, with usb_buffer_dmasync()
* calls to synchronize memory and dma state. It may not be used for
* calls to synchronize memory and dma state.
* control requests.
*
*
* Reverse the effect of this call with usb_buffer_unmap().
* Reverse the effect of this call with usb_buffer_unmap().
*/
*/
...
@@ -1311,7 +1311,6 @@ struct urb *usb_buffer_map (struct urb *urb)
...
@@ -1311,7 +1311,6 @@ struct urb *usb_buffer_map (struct urb *urb)
struct
device
*
controller
;
struct
device
*
controller
;
if
(
!
urb
if
(
!
urb
||
usb_pipecontrol
(
urb
->
pipe
)
||
!
urb
->
dev
||
!
urb
->
dev
||
!
(
bus
=
urb
->
dev
->
bus
)
||
!
(
bus
=
urb
->
dev
->
bus
)
||
!
(
controller
=
bus
->
controller
))
||
!
(
controller
=
bus
->
controller
))
...
@@ -1322,17 +1321,23 @@ struct urb *usb_buffer_map (struct urb *urb)
...
@@ -1322,17 +1321,23 @@ struct urb *usb_buffer_map (struct urb *urb)
urb
->
transfer_buffer
,
urb
->
transfer_buffer_length
,
urb
->
transfer_buffer
,
urb
->
transfer_buffer_length
,
usb_pipein
(
urb
->
pipe
)
usb_pipein
(
urb
->
pipe
)
?
DMA_FROM_DEVICE
:
DMA_TO_DEVICE
);
?
DMA_FROM_DEVICE
:
DMA_TO_DEVICE
);
if
(
usb_pipecontrol
(
urb
->
pipe
))
urb
->
setup_dma
=
dma_map_single
(
controller
,
urb
->
setup_packet
,
sizeof
(
struct
usb_ctrlrequest
),
DMA_TO_DEVICE
);
// FIXME generic api broken like pci, can't report errors
// FIXME generic api broken like pci, can't report errors
// if (urb->transfer_dma == DMA_ADDR_INVALID) return 0;
// if (urb->transfer_dma == DMA_ADDR_INVALID) return 0;
}
else
}
else
urb
->
transfer_dma
=
~
0
;
urb
->
transfer_dma
=
~
0
;
urb
->
transfer_flags
|=
URB_NO_DMA_MAP
;
urb
->
transfer_flags
|=
(
URB_NO_TRANSFER_DMA_MAP
|
URB_NO_SETUP_DMA_MAP
);
return
urb
;
return
urb
;
}
}
/**
/**
* usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s)
* usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s)
* @urb: urb whose transfer_buffer will be synchronized
* @urb: urb whose transfer_buffer
/setup_packet
will be synchronized
*/
*/
void
usb_buffer_dmasync
(
struct
urb
*
urb
)
void
usb_buffer_dmasync
(
struct
urb
*
urb
)
{
{
...
@@ -1340,17 +1345,23 @@ void usb_buffer_dmasync (struct urb *urb)
...
@@ -1340,17 +1345,23 @@ void usb_buffer_dmasync (struct urb *urb)
struct
device
*
controller
;
struct
device
*
controller
;
if
(
!
urb
if
(
!
urb
||
!
(
urb
->
transfer_flags
&
URB_NO_DMA_MAP
)
||
!
(
urb
->
transfer_flags
&
URB_NO_
TRANSFER_
DMA_MAP
)
||
!
urb
->
dev
||
!
urb
->
dev
||
!
(
bus
=
urb
->
dev
->
bus
)
||
!
(
bus
=
urb
->
dev
->
bus
)
||
!
(
controller
=
bus
->
controller
))
||
!
(
controller
=
bus
->
controller
))
return
;
return
;
if
(
controller
->
dma_mask
)
if
(
controller
->
dma_mask
)
{
dma_sync_single
(
controller
,
dma_sync_single
(
controller
,
urb
->
transfer_dma
,
urb
->
transfer_buffer_length
,
urb
->
transfer_dma
,
urb
->
transfer_buffer_length
,
usb_pipein
(
urb
->
pipe
)
usb_pipein
(
urb
->
pipe
)
?
DMA_FROM_DEVICE
:
DMA_TO_DEVICE
);
?
DMA_FROM_DEVICE
:
DMA_TO_DEVICE
);
if
(
usb_pipecontrol
(
urb
->
pipe
))
dma_sync_single
(
controller
,
urb
->
setup_dma
,
sizeof
(
struct
usb_ctrlrequest
),
DMA_TO_DEVICE
);
}
}
}
/**
/**
...
@@ -1365,18 +1376,25 @@ void usb_buffer_unmap (struct urb *urb)
...
@@ -1365,18 +1376,25 @@ void usb_buffer_unmap (struct urb *urb)
struct
device
*
controller
;
struct
device
*
controller
;
if
(
!
urb
if
(
!
urb
||
!
(
urb
->
transfer_flags
&
URB_NO_DMA_MAP
)
||
!
(
urb
->
transfer_flags
&
URB_NO_
TRANSFER_
DMA_MAP
)
||
!
urb
->
dev
||
!
urb
->
dev
||
!
(
bus
=
urb
->
dev
->
bus
)
||
!
(
bus
=
urb
->
dev
->
bus
)
||
!
(
controller
=
bus
->
controller
))
||
!
(
controller
=
bus
->
controller
))
return
;
return
;
if
(
controller
->
dma_mask
)
if
(
controller
->
dma_mask
)
{
dma_unmap_single
(
controller
,
dma_unmap_single
(
controller
,
urb
->
transfer_dma
,
urb
->
transfer_buffer_length
,
urb
->
transfer_dma
,
urb
->
transfer_buffer_length
,
usb_pipein
(
urb
->
pipe
)
usb_pipein
(
urb
->
pipe
)
?
DMA_FROM_DEVICE
:
DMA_TO_DEVICE
);
?
DMA_FROM_DEVICE
:
DMA_TO_DEVICE
);
urb
->
transfer_flags
&=
~
URB_NO_DMA_MAP
;
if
(
usb_pipecontrol
(
urb
->
pipe
))
dma_unmap_single
(
controller
,
urb
->
setup_dma
,
sizeof
(
struct
usb_ctrlrequest
),
DMA_TO_DEVICE
);
}
urb
->
transfer_flags
&=
~
(
URB_NO_TRANSFER_DMA_MAP
|
URB_NO_SETUP_DMA_MAP
);
}
}
/**
/**
...
@@ -1391,7 +1409,7 @@ void usb_buffer_unmap (struct urb *urb)
...
@@ -1391,7 +1409,7 @@ void usb_buffer_unmap (struct urb *urb)
*
*
* The caller is responsible for placing the resulting DMA addresses from
* The caller is responsible for placing the resulting DMA addresses from
* the scatterlist into URB transfer buffer pointers, and for setting the
* the scatterlist into URB transfer buffer pointers, and for setting the
* URB_NO_DMA_MAP transfer flag in each of those URBs.
* URB_NO_
TRANSFER_
DMA_MAP transfer flag in each of those URBs.
*
*
* Top I/O rates come from queuing URBs, instead of waiting for each one
* Top I/O rates come from queuing URBs, instead of waiting for each one
* to complete before starting the next I/O. This is particularly easy
* to complete before starting the next I/O. This is particularly easy
...
...
drivers/usb/host/ehci-dbg.c
View file @
5bcd0bb6
...
@@ -114,20 +114,29 @@ static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {}
...
@@ -114,20 +114,29 @@ static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {}
#ifdef DEBUG
#ifdef DEBUG
static
void
__attribute__
((
__unused__
))
dbg_qtd
(
char
*
label
,
struct
ehci_hcd
*
ehci
,
struct
ehci_qtd
*
qtd
)
{
ehci_dbg
(
ehci
,
"%s td %p n%08x %08x t%08x p0=%08x
\n
"
,
label
,
qtd
,
cpu_to_le32p
(
&
qtd
->
hw_next
),
cpu_to_le32p
(
&
qtd
->
hw_alt_next
),
cpu_to_le32p
(
&
qtd
->
hw_token
),
cpu_to_le32p
(
&
qtd
->
hw_buf
[
0
]));
if
(
qtd
->
hw_buf
[
1
])
ehci_dbg
(
ehci
,
" p1=%08x p2=%08x p3=%08x p4=%08x
\n
"
,
cpu_to_le32p
(
&
qtd
->
hw_buf
[
1
]),
cpu_to_le32p
(
&
qtd
->
hw_buf
[
2
]),
cpu_to_le32p
(
&
qtd
->
hw_buf
[
3
]),
cpu_to_le32p
(
&
qtd
->
hw_buf
[
4
]));
}
static
void
__attribute__
((
__unused__
))
static
void
__attribute__
((
__unused__
))
dbg_qh
(
char
*
label
,
struct
ehci_hcd
*
ehci
,
struct
ehci_qh
*
qh
)
dbg_qh
(
char
*
label
,
struct
ehci_hcd
*
ehci
,
struct
ehci_qh
*
qh
)
{
{
dbg
(
"%s %p n%08x info1 %x info2 %x hw_curr %x qtd_next %x
"
,
label
,
ehci_dbg
(
ehci
,
"%s qh %p n%08x info %x %x qtd %x
\n
"
,
label
,
qh
,
qh
->
hw_next
,
qh
->
hw_info1
,
qh
->
hw_info2
,
qh
,
qh
->
hw_next
,
qh
->
hw_info1
,
qh
->
hw_info2
,
qh
->
hw_current
,
qh
->
hw_qtd_next
);
qh
->
hw_current
);
dbg
(
" alt+nak+t= %x, token= %x, page0= %x, page1= %x"
,
dbg_qtd
(
"overlay"
,
ehci
,
(
struct
ehci_qtd
*
)
&
qh
->
hw_qtd_next
);
qh
->
hw_alt_next
,
qh
->
hw_token
,
qh
->
hw_buf
[
0
],
qh
->
hw_buf
[
1
]);
if
(
qh
->
hw_buf
[
2
])
{
dbg
(
" page2= %x, page3= %x, page4= %x"
,
qh
->
hw_buf
[
2
],
qh
->
hw_buf
[
3
],
qh
->
hw_buf
[
4
]);
}
}
}
static
int
__attribute__
((
__unused__
))
static
int
__attribute__
((
__unused__
))
...
@@ -284,8 +293,7 @@ static inline char token_mark (u32 token)
...
@@ -284,8 +293,7 @@ static inline char token_mark (u32 token)
return
'*'
;
return
'*'
;
if
(
token
&
QTD_STS_HALT
)
if
(
token
&
QTD_STS_HALT
)
return
'-'
;
return
'-'
;
if
(
QTD_PID
(
token
)
!=
1
/* not IN: OUT or SETUP */
if
(
!
IS_SHORT_READ
(
token
))
||
QTD_LENGTH
(
token
)
==
0
)
return
' '
;
return
' '
;
/* tries to advance through hw_alt_next */
/* tries to advance through hw_alt_next */
return
'/'
;
return
'/'
;
...
@@ -307,11 +315,14 @@ static void qh_lines (
...
@@ -307,11 +315,14 @@ static void qh_lines (
char
*
next
=
*
nextp
;
char
*
next
=
*
nextp
;
char
mark
;
char
mark
;
if
(
qh
->
hw_qtd_next
==
EHCI_LIST_END
)
/* NEC does this */
mark
=
'@'
;
else
mark
=
token_mark
(
qh
->
hw_token
);
mark
=
token_mark
(
qh
->
hw_token
);
if
(
mark
==
'/'
)
{
/* qh_alt_next controls qh advance? */
if
(
mark
==
'/'
)
{
/* qh_alt_next controls qh advance? */
if
((
qh
->
hw_alt_next
&
QTD_MASK
)
==
ehci
->
async
->
hw_alt_next
)
if
((
qh
->
hw_alt_next
&
QTD_MASK
)
==
ehci
->
async
->
hw_alt_next
)
mark
=
'#'
;
/* blocked */
mark
=
'#'
;
/* blocked */
else
if
(
qh
->
hw_alt_next
&
cpu_to_le32
(
0x01
)
)
else
if
(
qh
->
hw_alt_next
==
EHCI_LIST_END
)
mark
=
'.'
;
/* use hw_qtd_next */
mark
=
'.'
;
/* use hw_qtd_next */
/* else alt_next points to some other qtd */
/* else alt_next points to some other qtd */
}
}
...
@@ -324,7 +335,7 @@ static void qh_lines (
...
@@ -324,7 +335,7 @@ static void qh_lines (
(
scratch
>>
8
)
&
0x000f
,
(
scratch
>>
8
)
&
0x000f
,
scratch
,
cpu_to_le32p
(
&
qh
->
hw_info2
),
scratch
,
cpu_to_le32p
(
&
qh
->
hw_info2
),
cpu_to_le32p
(
&
qh
->
hw_token
),
mark
,
cpu_to_le32p
(
&
qh
->
hw_token
),
mark
,
(
cpu_to_le32
(
0x8000000
)
&
qh
->
hw_token
)
(
__constant_cpu_to_le32
(
QTD_TOGGLE
)
&
qh
->
hw_token
)
?
"data0"
:
"data1"
,
?
"data0"
:
"data1"
,
(
cpu_to_le32p
(
&
qh
->
hw_alt_next
)
>>
1
)
&
0x0f
);
(
cpu_to_le32p
(
&
qh
->
hw_alt_next
)
>>
1
)
&
0x0f
);
size
-=
temp
;
size
-=
temp
;
...
@@ -390,6 +401,8 @@ show_async (struct device *dev, char *buf)
...
@@ -390,6 +401,8 @@ show_async (struct device *dev, char *buf)
char
*
next
;
char
*
next
;
struct
ehci_qh
*
qh
;
struct
ehci_qh
*
qh
;
*
buf
=
0
;
pdev
=
container_of
(
dev
,
struct
pci_dev
,
dev
);
pdev
=
container_of
(
dev
,
struct
pci_dev
,
dev
);
ehci
=
container_of
(
pci_get_drvdata
(
pdev
),
struct
ehci_hcd
,
hcd
);
ehci
=
container_of
(
pci_get_drvdata
(
pdev
),
struct
ehci_hcd
,
hcd
);
next
=
buf
;
next
=
buf
;
...
@@ -412,7 +425,7 @@ show_async (struct device *dev, char *buf)
...
@@ -412,7 +425,7 @@ show_async (struct device *dev, char *buf)
}
}
spin_unlock_irqrestore
(
&
ehci
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
ehci
->
lock
,
flags
);
return
PAGE_SIZE
-
size
;
return
strlen
(
buf
)
;
}
}
static
DEVICE_ATTR
(
async
,
S_IRUGO
,
show_async
,
NULL
);
static
DEVICE_ATTR
(
async
,
S_IRUGO
,
show_async
,
NULL
);
...
@@ -548,7 +561,8 @@ show_registers (struct device *dev, char *buf)
...
@@ -548,7 +561,8 @@ show_registers (struct device *dev, char *buf)
/* Capability Registers */
/* Capability Registers */
i
=
readw
(
&
ehci
->
caps
->
hci_version
);
i
=
readw
(
&
ehci
->
caps
->
hci_version
);
temp
=
snprintf
(
next
,
size
,
temp
=
snprintf
(
next
,
size
,
"EHCI %x.%02x, hcd state %d (version "
DRIVER_VERSION
")
\n
"
,
"%s
\n
EHCI %x.%02x, hcd state %d (driver "
DRIVER_VERSION
")
\n
"
,
pdev
->
dev
.
name
,
i
>>
8
,
i
&
0x0ff
,
ehci
->
hcd
.
state
);
i
>>
8
,
i
&
0x0ff
,
ehci
->
hcd
.
state
);
size
-=
temp
;
size
-=
temp
;
next
+=
temp
;
next
+=
temp
;
...
...
drivers/usb/host/ehci-hcd.c
View file @
5bcd0bb6
...
@@ -39,13 +39,10 @@
...
@@ -39,13 +39,10 @@
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/reboot.h>
#include <linux/reboot.h>
#include <linux/usb.h>
#include <linux/usb.h>
#include <linux/moduleparam.h>
#include <linux/version.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
#include "../hcd.h"
#else
#include "../core/hcd.h"
#include "../core/hcd.h"
#endif
#include <asm/byteorder.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/io.h>
...
@@ -94,11 +91,11 @@
...
@@ -94,11 +91,11 @@
* 2001-June Works with usb-storage and NEC EHCI on 2.4
* 2001-June Works with usb-storage and NEC EHCI on 2.4
*/
*/
#define DRIVER_VERSION "2003-J
an-22
"
#define DRIVER_VERSION "2003-J
un-13
"
#define DRIVER_AUTHOR "David Brownell"
#define DRIVER_AUTHOR "David Brownell"
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
static
const
char
hcd_name
[]
=
"ehci
-
hcd"
;
static
const
char
hcd_name
[]
=
"ehci
_
hcd"
;
// #define EHCI_VERBOSE_DEBUG
// #define EHCI_VERBOSE_DEBUG
...
@@ -123,7 +120,7 @@ static const char hcd_name [] = "ehci-hcd";
...
@@ -123,7 +120,7 @@ static const char hcd_name [] = "ehci-hcd";
/* Initial IRQ latency: lower than default */
/* Initial IRQ latency: lower than default */
static
int
log2_irq_thresh
=
0
;
// 0 to 6
static
int
log2_irq_thresh
=
0
;
// 0 to 6
MODULE_PARM
(
log2_irq_thresh
,
"i"
);
module_param
(
log2_irq_thresh
,
int
,
S_IRUGO
);
MODULE_PARM_DESC
(
log2_irq_thresh
,
"log2 IRQ latency, 1-64 microframes"
);
MODULE_PARM_DESC
(
log2_irq_thresh
,
"log2 IRQ latency, 1-64 microframes"
);
#define INTR_MASK (STS_IAA | STS_FATAL | STS_ERR | STS_INT)
#define INTR_MASK (STS_IAA | STS_FATAL | STS_ERR | STS_INT)
...
@@ -1020,7 +1017,8 @@ static int __init init (void)
...
@@ -1020,7 +1017,8 @@ static int __init init (void)
if
(
usb_disabled
())
if
(
usb_disabled
())
return
-
ENODEV
;
return
-
ENODEV
;
dbg
(
"block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd"
,
pr_debug
(
"%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd
\n
"
,
hcd_name
,
sizeof
(
struct
ehci_qh
),
sizeof
(
struct
ehci_qtd
),
sizeof
(
struct
ehci_qh
),
sizeof
(
struct
ehci_qtd
),
sizeof
(
struct
ehci_itd
),
sizeof
(
struct
ehci_sitd
));
sizeof
(
struct
ehci_itd
),
sizeof
(
struct
ehci_sitd
));
...
...
drivers/usb/host/ehci-q.c
View file @
5bcd0bb6
...
@@ -88,7 +88,6 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,
...
@@ -88,7 +88,6 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,
static
inline
void
static
inline
void
qh_update
(
struct
ehci_hcd
*
ehci
,
struct
ehci_qh
*
qh
,
struct
ehci_qtd
*
qtd
)
qh_update
(
struct
ehci_hcd
*
ehci
,
struct
ehci_qh
*
qh
,
struct
ehci_qtd
*
qtd
)
{
{
qh
->
hw_current
=
0
;
qh
->
hw_qtd_next
=
QTD_NEXT
(
qtd
->
qtd_dma
);
qh
->
hw_qtd_next
=
QTD_NEXT
(
qtd
->
qtd_dma
);
qh
->
hw_alt_next
=
EHCI_LIST_END
;
qh
->
hw_alt_next
=
EHCI_LIST_END
;
...
@@ -99,8 +98,6 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
...
@@ -99,8 +98,6 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
static
void
qtd_copy_status
(
static
void
qtd_copy_status
(
struct
ehci_hcd
*
ehci
,
struct
ehci_hcd
*
ehci
,
struct
urb
*
urb
,
struct
urb
*
urb
,
...
@@ -279,16 +276,15 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
...
@@ -279,16 +276,15 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
/* hardware copies qtd out of qh overlay */
/* hardware copies qtd out of qh overlay */
rmb
();
rmb
();
token
=
le32_to_cpu
(
qtd
->
hw_token
);
token
=
le32_to_cpu
(
qtd
->
hw_token
);
stopped
=
stopped
||
(
HALT_BIT
&
qh
->
hw_token
)
!=
0
||
(
ehci
->
hcd
.
state
==
USB_STATE_HALT
);
/* always clean up qtds the hc de-activated */
/* always clean up qtds the hc de-activated */
if
((
token
&
QTD_STS_ACTIVE
)
==
0
)
{
if
((
token
&
QTD_STS_ACTIVE
)
==
0
)
{
/* magic dummy for short reads; won't advance */
if
((
token
&
QTD_STS_HALT
)
!=
0
)
{
if
(
IS_SHORT_READ
(
token
)
stopped
=
1
;
&&
!
(
token
&
QTD_STS_HALT
)
/* magic dummy for some short reads; qh won't advance */
}
else
if
(
IS_SHORT_READ
(
token
)
&&
(
qh
->
hw_alt_next
&
QTD_MASK
)
&&
(
qh
->
hw_alt_next
&
QTD_MASK
)
==
ehci
->
async
->
hw_alt_next
)
{
==
ehci
->
async
->
hw_alt_next
)
{
stopped
=
1
;
stopped
=
1
;
...
@@ -296,10 +292,13 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
...
@@ -296,10 +292,13 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
}
}
/* stop scanning when we reach qtds the hc is using */
/* stop scanning when we reach qtds the hc is using */
}
else
if
(
likely
(
!
stopped
))
{
}
else
if
(
likely
(
!
stopped
||
HCD_IS_RUNNING
(
ehci
->
hcd
.
state
)))
{
break
;
break
;
}
else
{
}
else
{
stopped
=
1
;
/* ignore active urbs unless some previous qtd
/* ignore active urbs unless some previous qtd
* for the urb faulted (including short read) or
* for the urb faulted (including short read) or
* its urb was canceled. we may patch qh or qtds.
* its urb was canceled. we may patch qh or qtds.
...
@@ -358,12 +357,20 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
...
@@ -358,12 +357,20 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
qh
->
qh_state
=
state
;
qh
->
qh_state
=
state
;
/* update qh after fault cleanup */
/* update qh after fault cleanup */
if
(
unlikely
((
HALT_BIT
&
qh
->
hw_token
)
!=
0
))
{
if
(
unlikely
(
stopped
!=
0
)
qh_update
(
ehci
,
qh
,
/* some EHCI 0.95 impls will overlay dummy qtds */
list_empty
(
&
qh
->
qtd_list
)
||
qh
->
hw_qtd_next
==
EHCI_LIST_END
)
{
?
qh
->
dummy
if
(
list_empty
(
&
qh
->
qtd_list
))
:
list_entry
(
qh
->
qtd_list
.
next
,
end
=
qh
->
dummy
;
struct
ehci_qtd
,
qtd_list
));
else
{
end
=
list_entry
(
qh
->
qtd_list
.
next
,
struct
ehci_qtd
,
qtd_list
);
/* first qtd may already be partially processed */
if
(
cpu_to_le32
(
end
->
qtd_dma
)
==
qh
->
hw_current
)
end
=
0
;
}
if
(
end
)
qh_update
(
ehci
,
qh
,
end
);
}
}
return
count
;
return
count
;
...
@@ -788,11 +795,6 @@ static struct ehci_qh *qh_append_tds (
...
@@ -788,11 +795,6 @@ static struct ehci_qh *qh_append_tds (
}
}
}
}
/* FIXME: changing config or interface setting is not
* supported yet. preferred fix is for usbcore to tell
* us to clear out each endpoint's state, but...
*/
/* usb_clear_halt() means qh data toggle gets reset */
/* usb_clear_halt() means qh data toggle gets reset */
if
(
unlikely
(
!
usb_gettoggle
(
urb
->
dev
,
if
(
unlikely
(
!
usb_gettoggle
(
urb
->
dev
,
(
epnum
&
0x0f
),
!
(
epnum
&
0x10
)))
(
epnum
&
0x0f
),
!
(
epnum
&
0x10
)))
...
...
drivers/usb/host/ehci.h
View file @
5bcd0bb6
...
@@ -290,7 +290,10 @@ struct ehci_qtd {
...
@@ -290,7 +290,10 @@ struct ehci_qtd {
size_t
length
;
/* length of buffer */
size_t
length
;
/* length of buffer */
}
__attribute__
((
aligned
(
32
)));
}
__attribute__
((
aligned
(
32
)));
#define QTD_MASK cpu_to_le32 (~0x1f)
/* mask NakCnt+T in qh->hw_alt_next */
/* mask NakCnt+T in qh->hw_alt_next */
#define QTD_MASK __constant_cpu_to_le32 (~0x1f)
#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
...
...
drivers/usb/input/aiptek.c
View file @
5bcd0bb6
...
@@ -330,7 +330,7 @@ aiptek_probe(struct usb_interface *intf,
...
@@ -330,7 +330,7 @@ aiptek_probe(struct usb_interface *intf,
aiptek
->
data
,
aiptek
->
features
->
pktlen
,
aiptek
->
data
,
aiptek
->
features
->
pktlen
,
aiptek
->
features
->
irq
,
aiptek
,
endpoint
->
bInterval
);
aiptek
->
features
->
irq
,
aiptek
,
endpoint
->
bInterval
);
aiptek
->
irq
->
transfer_dma
=
aiptek
->
data_dma
;
aiptek
->
irq
->
transfer_dma
=
aiptek
->
data_dma
;
aiptek
->
irq
->
transfer_flags
|=
URB_NO_DMA_MAP
;
aiptek
->
irq
->
transfer_flags
|=
URB_NO_
TRANSFER_
DMA_MAP
;
input_register_device
(
&
aiptek
->
dev
);
input_register_device
(
&
aiptek
->
dev
);
...
...
drivers/usb/input/hid-core.c
View file @
5bcd0bb6
...
@@ -1518,7 +1518,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
...
@@ -1518,7 +1518,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
usb_fill_int_urb
(
hid
->
urbin
,
dev
,
pipe
,
hid
->
inbuf
,
0
,
usb_fill_int_urb
(
hid
->
urbin
,
dev
,
pipe
,
hid
->
inbuf
,
0
,
hid_irq_in
,
hid
,
endpoint
->
bInterval
);
hid_irq_in
,
hid
,
endpoint
->
bInterval
);
hid
->
urbin
->
transfer_dma
=
hid
->
inbuf_dma
;
hid
->
urbin
->
transfer_dma
=
hid
->
inbuf_dma
;
hid
->
urbin
->
transfer_flags
|=
URB_NO_DMA_MAP
;
hid
->
urbin
->
transfer_flags
|=
URB_NO_
TRANSFER_
DMA_MAP
;
}
else
{
}
else
{
if
(
hid
->
urbout
)
if
(
hid
->
urbout
)
continue
;
continue
;
...
@@ -1528,7 +1528,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
...
@@ -1528,7 +1528,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
usb_fill_bulk_urb
(
hid
->
urbout
,
dev
,
pipe
,
hid
->
outbuf
,
0
,
usb_fill_bulk_urb
(
hid
->
urbout
,
dev
,
pipe
,
hid
->
outbuf
,
0
,
hid_irq_out
,
hid
);
hid_irq_out
,
hid
);
hid
->
urbout
->
transfer_dma
=
hid
->
outbuf_dma
;
hid
->
urbout
->
transfer_dma
=
hid
->
outbuf_dma
;
hid
->
urbout
->
transfer_flags
|=
URB_NO_DMA_MAP
;
hid
->
urbout
->
transfer_flags
|=
URB_NO_
TRANSFER_
DMA_MAP
;
}
}
}
}
...
@@ -1577,7 +1577,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
...
@@ -1577,7 +1577,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
hid
->
ctrlbuf
,
1
,
hid_ctrl
,
hid
);
hid
->
ctrlbuf
,
1
,
hid_ctrl
,
hid
);
hid
->
urbctrl
->
setup_dma
=
hid
->
cr_dma
;
hid
->
urbctrl
->
setup_dma
=
hid
->
cr_dma
;
hid
->
urbctrl
->
transfer_dma
=
hid
->
ctrlbuf_dma
;
hid
->
urbctrl
->
transfer_dma
=
hid
->
ctrlbuf_dma
;
hid
->
urbctrl
->
transfer_flags
|=
URB_NO_DMA_MAP
;
hid
->
urbctrl
->
transfer_flags
|=
(
URB_NO_TRANSFER_DMA_MAP
|
URB_NO_SETUP_DMA_MAP
);
return
hid
;
return
hid
;
...
...
drivers/usb/input/kbtab.c
View file @
5bcd0bb6
...
@@ -181,7 +181,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
...
@@ -181,7 +181,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
kbtab
->
data
,
8
,
kbtab
->
data
,
8
,
kbtab_irq
,
kbtab
,
endpoint
->
bInterval
);
kbtab_irq
,
kbtab
,
endpoint
->
bInterval
);
kbtab
->
irq
->
transfer_dma
=
kbtab
->
data_dma
;
kbtab
->
irq
->
transfer_dma
=
kbtab
->
data_dma
;
kbtab
->
irq
->
transfer_flags
|=
URB_NO_DMA_MAP
;
kbtab
->
irq
->
transfer_flags
|=
URB_NO_
TRANSFER_
DMA_MAP
;
input_register_device
(
&
kbtab
->
dev
);
input_register_device
(
&
kbtab
->
dev
);
...
...
drivers/usb/input/powermate.c
View file @
5bcd0bb6
...
@@ -180,7 +180,7 @@ static void powermate_sync_state(struct powermate_device *pm)
...
@@ -180,7 +180,7 @@ static void powermate_sync_state(struct powermate_device *pm)
(
void
*
)
pm
->
configcr
,
0
,
0
,
(
void
*
)
pm
->
configcr
,
0
,
0
,
powermate_config_complete
,
pm
);
powermate_config_complete
,
pm
);
pm
->
config
->
setup_dma
=
pm
->
configcr_dma
;
pm
->
config
->
setup_dma
=
pm
->
configcr_dma
;
pm
->
config
->
transfer_flags
|=
URB_NO_DMA_MAP
;
pm
->
config
->
transfer_flags
|=
URB_NO_
SETUP_
DMA_MAP
;
if
(
usb_submit_urb
(
pm
->
config
,
GFP_ATOMIC
))
if
(
usb_submit_urb
(
pm
->
config
,
GFP_ATOMIC
))
printk
(
KERN_ERR
"powermate: usb_submit_urb(config) failed"
);
printk
(
KERN_ERR
"powermate: usb_submit_urb(config) failed"
);
...
@@ -355,7 +355,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
...
@@ -355,7 +355,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
POWERMATE_PAYLOAD_SIZE
,
powermate_irq
,
POWERMATE_PAYLOAD_SIZE
,
powermate_irq
,
pm
,
endpoint
->
bInterval
);
pm
,
endpoint
->
bInterval
);
pm
->
irq
->
transfer_dma
=
pm
->
data_dma
;
pm
->
irq
->
transfer_dma
=
pm
->
data_dma
;
pm
->
irq
->
transfer_flags
|=
URB_NO_DMA_MAP
;
pm
->
irq
->
transfer_flags
|=
URB_NO_
TRANSFER_
DMA_MAP
;
/* register our interrupt URB with the USB system */
/* register our interrupt URB with the USB system */
if
(
usb_submit_urb
(
pm
->
irq
,
GFP_KERNEL
))
{
if
(
usb_submit_urb
(
pm
->
irq
,
GFP_KERNEL
))
{
...
...
drivers/usb/input/usbkbd.c
View file @
5bcd0bb6
...
@@ -282,7 +282,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
...
@@ -282,7 +282,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
kbd
->
new
,
(
maxp
>
8
?
8
:
maxp
),
kbd
->
new
,
(
maxp
>
8
?
8
:
maxp
),
usb_kbd_irq
,
kbd
,
endpoint
->
bInterval
);
usb_kbd_irq
,
kbd
,
endpoint
->
bInterval
);
kbd
->
irq
->
transfer_dma
=
kbd
->
new_dma
;
kbd
->
irq
->
transfer_dma
=
kbd
->
new_dma
;
kbd
->
irq
->
transfer_flags
|=
URB_NO_DMA_MAP
;
kbd
->
irq
->
transfer_flags
|=
URB_NO_
TRANSFER_
DMA_MAP
;
kbd
->
cr
->
bRequestType
=
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
;
kbd
->
cr
->
bRequestType
=
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
;
kbd
->
cr
->
bRequest
=
0x09
;
kbd
->
cr
->
bRequest
=
0x09
;
...
@@ -325,7 +325,8 @@ static int usb_kbd_probe(struct usb_interface *iface,
...
@@ -325,7 +325,8 @@ static int usb_kbd_probe(struct usb_interface *iface,
usb_kbd_led
,
kbd
);
usb_kbd_led
,
kbd
);
kbd
->
led
->
setup_dma
=
kbd
->
cr_dma
;
kbd
->
led
->
setup_dma
=
kbd
->
cr_dma
;
kbd
->
led
->
transfer_dma
=
kbd
->
leds_dma
;
kbd
->
led
->
transfer_dma
=
kbd
->
leds_dma
;
kbd
->
led
->
transfer_flags
|=
URB_NO_DMA_MAP
;
kbd
->
led
->
transfer_flags
|=
(
URB_NO_TRANSFER_DMA_MAP
|
URB_NO_SETUP_DMA_MAP
);
input_register_device
(
&
kbd
->
dev
);
input_register_device
(
&
kbd
->
dev
);
...
...
drivers/usb/input/usbmouse.c
View file @
5bcd0bb6
...
@@ -207,7 +207,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
...
@@ -207,7 +207,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
(
maxp
>
8
?
8
:
maxp
),
(
maxp
>
8
?
8
:
maxp
),
usb_mouse_irq
,
mouse
,
endpoint
->
bInterval
);
usb_mouse_irq
,
mouse
,
endpoint
->
bInterval
);
mouse
->
irq
->
transfer_dma
=
mouse
->
data_dma
;
mouse
->
irq
->
transfer_dma
=
mouse
->
data_dma
;
mouse
->
irq
->
transfer_flags
|=
URB_NO_DMA_MAP
;
mouse
->
irq
->
transfer_flags
|=
URB_NO_
TRANSFER_
DMA_MAP
;
input_register_device
(
&
mouse
->
dev
);
input_register_device
(
&
mouse
->
dev
);
printk
(
KERN_INFO
"input: %s on %s
\n
"
,
mouse
->
name
,
path
);
printk
(
KERN_INFO
"input: %s on %s
\n
"
,
mouse
->
name
,
path
);
...
...
drivers/usb/input/wacom.c
View file @
5bcd0bb6
...
@@ -590,7 +590,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
...
@@ -590,7 +590,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom
->
data
,
wacom
->
features
->
pktlen
,
wacom
->
data
,
wacom
->
features
->
pktlen
,
wacom
->
features
->
irq
,
wacom
,
endpoint
->
bInterval
);
wacom
->
features
->
irq
,
wacom
,
endpoint
->
bInterval
);
wacom
->
irq
->
transfer_dma
=
wacom
->
data_dma
;
wacom
->
irq
->
transfer_dma
=
wacom
->
data_dma
;
wacom
->
irq
->
transfer_flags
|=
URB_NO_DMA_MAP
;
wacom
->
irq
->
transfer_flags
|=
URB_NO_
TRANSFER_
DMA_MAP
;
input_register_device
(
&
wacom
->
dev
);
input_register_device
(
&
wacom
->
dev
);
...
...
drivers/usb/input/xpad.c
View file @
5bcd0bb6
...
@@ -259,7 +259,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
...
@@ -259,7 +259,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
xpad
->
idata
,
XPAD_PKT_LEN
,
xpad_irq_in
,
xpad
->
idata
,
XPAD_PKT_LEN
,
xpad_irq_in
,
xpad
,
ep_irq_in
->
bInterval
);
xpad
,
ep_irq_in
->
bInterval
);
xpad
->
irq_in
->
transfer_dma
=
xpad
->
idata_dma
;
xpad
->
irq_in
->
transfer_dma
=
xpad
->
idata_dma
;
xpad
->
irq_in
->
transfer_flags
|=
URB_NO_DMA_MAP
;
xpad
->
irq_in
->
transfer_flags
|=
URB_NO_
TRANSFER_
DMA_MAP
;
xpad
->
udev
=
udev
;
xpad
->
udev
=
udev
;
...
...
drivers/usb/misc/speedtch.c
View file @
5bcd0bb6
This diff is collapsed.
Click to expand it.
drivers/usb/misc/usbtest.c
View file @
5bcd0bb6
...
@@ -107,7 +107,7 @@ static struct urb *simple_alloc_urb (
...
@@ -107,7 +107,7 @@ static struct urb *simple_alloc_urb (
urb
->
interval
=
(
udev
->
speed
==
USB_SPEED_HIGH
)
urb
->
interval
=
(
udev
->
speed
==
USB_SPEED_HIGH
)
?
(
INTERRUPT_RATE
<<
3
)
?
(
INTERRUPT_RATE
<<
3
)
:
INTERRUPT_RATE
;
:
INTERRUPT_RATE
;
urb
->
transfer_flags
=
URB_NO_DMA_MAP
;
urb
->
transfer_flags
=
URB_NO_
TRANSFER_
DMA_MAP
;
if
(
usb_pipein
(
pipe
))
if
(
usb_pipein
(
pipe
))
urb
->
transfer_flags
|=
URB_SHORT_NOT_OK
;
urb
->
transfer_flags
|=
URB_SHORT_NOT_OK
;
urb
->
transfer_buffer
=
usb_buffer_alloc
(
udev
,
bytes
,
SLAB_KERNEL
,
urb
->
transfer_buffer
=
usb_buffer_alloc
(
udev
,
bytes
,
SLAB_KERNEL
,
...
...
include/linux/usb.h
View file @
5bcd0bb6
...
@@ -492,8 +492,9 @@ extern int usb_disabled(void);
...
@@ -492,8 +492,9 @@ extern int usb_disabled(void);
*/
*/
#define URB_SHORT_NOT_OK 0x0001
/* report short reads as errors */
#define URB_SHORT_NOT_OK 0x0001
/* report short reads as errors */
#define URB_ISO_ASAP 0x0002
/* iso-only, urb->start_frame ignored */
#define URB_ISO_ASAP 0x0002
/* iso-only, urb->start_frame ignored */
#define URB_NO_DMA_MAP 0x0004
/* urb->*_dma are valid on submit */
#define URB_NO_TRANSFER_DMA_MAP 0x0004
/* urb->transfer_dma valid on submit */
#define URB_ASYNC_UNLINK 0x0008
/* usb_unlink_urb() returns asap */
#define URB_NO_SETUP_DMA_MAP 0x0008
/* urb->setup_dma valid on submit */
#define URB_ASYNC_UNLINK 0x0010
/* usb_unlink_urb() returns asap */
#define URB_NO_FSBR 0x0020
/* UHCI-specific */
#define URB_NO_FSBR 0x0020
/* UHCI-specific */
#define URB_ZERO_PACKET 0x0040
/* Finish bulk OUTs with short packet */
#define URB_ZERO_PACKET 0x0040
/* Finish bulk OUTs with short packet */
#define URB_NO_INTERRUPT 0x0080
/* HINT: no non-error interrupt needed */
#define URB_NO_INTERRUPT 0x0080
/* HINT: no non-error interrupt needed */
...
@@ -531,14 +532,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
...
@@ -531,14 +532,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* submission, unlinking, or operation are handled. Different
* submission, unlinking, or operation are handled. Different
* kinds of URB can use different flags.
* kinds of URB can use different flags.
* @transfer_buffer: This identifies the buffer to (or from) which
* @transfer_buffer: This identifies the buffer to (or from) which
* the I/O request will be performed (unless URB_NO_
DMA_MAP is set).
* the I/O request will be performed (unless URB_NO_
TRANSFER_DMA_MAP
*
This buffer must be suitable for DMA; allocate it with kmalloc()
*
is set). This buffer must be suitable for DMA; allocate it with
*
or equivalent. For transfers to "in" endpoints, contents of
*
kmalloc() or equivalent. For transfers to "in" endpoints, contents
* this buffer will be modified. This buffer is used for data
*
of
this buffer will be modified. This buffer is used for data
* phases of control transfers.
* phases of control transfers.
* @transfer_dma: When transfer_flags includes URB_NO_DMA_MAP, the device
* @transfer_dma: When transfer_flags includes URB_NO_TRANSFER_DMA_MAP,
* driver is saying that it provided this DMA address, which the host
* the device driver is saying that it provided this DMA address,
* controller driver should use instead of the transfer_buffer.
* which the host controller driver should use in preference to the
* transfer_buffer.
* @transfer_buffer_length: How big is transfer_buffer. The transfer may
* @transfer_buffer_length: How big is transfer_buffer. The transfer may
* be broken up into chunks according to the current maximum packet
* be broken up into chunks according to the current maximum packet
* size for the endpoint, which is a function of the configuration
* size for the endpoint, which is a function of the configuration
...
@@ -553,11 +555,10 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
...
@@ -553,11 +555,10 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* @setup_packet: Only used for control transfers, this points to eight bytes
* @setup_packet: Only used for control transfers, this points to eight bytes
* of setup data. Control transfers always start by sending this data
* of setup data. Control transfers always start by sending this data
* to the device. Then transfer_buffer is read or written, if needed.
* to the device. Then transfer_buffer is read or written, if needed.
* (Not used when URB_NO_DMA_MAP is set.)
* @setup_dma: For control transfers with URB_NO_SETUP_DMA_MAP set, the
* @setup_dma: For control transfers with URB_NO_DMA_MAP set, the device
* device driver has provided this DMA address for the setup packet.
* driver has provided this DMA address for the setup packet. The
* The host controller driver should use this in preference to
* host controller driver should use this instead of setup_buffer.
* setup_packet.
* If there is a data phase, its buffer is identified by transfer_dma.
* @start_frame: Returns the initial frame for interrupt or isochronous
* @start_frame: Returns the initial frame for interrupt or isochronous
* transfers.
* transfers.
* @number_of_packets: Lists the number of ISO transfer buffers.
* @number_of_packets: Lists the number of ISO transfer buffers.
...
@@ -589,13 +590,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
...
@@ -589,13 +590,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* bounce buffer or talking to an IOMMU),
* bounce buffer or talking to an IOMMU),
* although they're cheap on commodity x86 and ppc hardware.
* although they're cheap on commodity x86 and ppc hardware.
*
*
* Alternatively, drivers may pass the URB_NO_DMA_MAP transfer flag, which
* Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
* tells the host controller driver that no such mapping is needed since
* which tell the host controller driver that no such mapping is needed since
* the device driver is DMA-aware. For example, they might allocate a DMA
* the device driver is DMA-aware. For example, a device driver might
* buffer with usb_buffer_alloc(), or call usb_buffer_map().
* allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
* When this transfer flag is provided, host controller drivers will use the
* When these transfer flags are provided, host controller drivers will
* dma addresses found in the transfer_dma and/or setup_dma fields rather than
* attempt to use the dma addresses found in the transfer_dma and/or
* determing a dma address themselves.
* setup_dma fields rather than determining a dma address themselves. (Note
* that transfer_buffer and setup_packet must still be set because not all
* host controllers use DMA, nor do virtual root hubs).
*
*
* Initialization:
* Initialization:
*
*
...
@@ -614,7 +617,11 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
...
@@ -614,7 +617,11 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* should always terminate with a short packet, even if it means adding an
* should always terminate with a short packet, even if it means adding an
* extra zero length packet.
* extra zero length packet.
*
*
* Control URBs must provide a setup_packet.
* Control URBs must provide a setup_packet. The setup_packet and
* transfer_buffer may each be mapped for DMA or not, independently of
* the other. The transfer_flags bits URB_NO_TRANSFER_DMA_MAP and
* URB_NO_SETUP_DMA_MAP indicate which buffers have already been mapped.
* URB_NO_SETUP_DMA_MAP is ignored for non-control URBs.
*
*
* Interrupt UBS must provide an interval, saying how often (in milliseconds
* Interrupt UBS must provide an interval, saying how often (in milliseconds
* or, for highspeed devices, 125 microsecond units)
* or, for highspeed devices, 125 microsecond units)
...
...
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