Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
89f0f973
Commit
89f0f973
authored
Nov 13, 2002
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Plain Diff
Merge kroah.com:/home/greg/linux/BK/bleeding_edge-2.5
into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents
2c0889e4
bbed5f2f
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
402 additions
and
536 deletions
+402
-536
drivers/usb/Makefile
drivers/usb/Makefile
+1
-6
drivers/usb/class/Kconfig
drivers/usb/class/Kconfig
+10
-8
drivers/usb/class/usblp.c
drivers/usb/class/usblp.c
+52
-15
drivers/usb/core/driverfs.c
drivers/usb/core/driverfs.c
+8
-0
drivers/usb/core/hcd.c
drivers/usb/core/hcd.c
+37
-42
drivers/usb/core/usb.c
drivers/usb/core/usb.c
+32
-31
drivers/usb/host/Kconfig
drivers/usb/host/Kconfig
+1
-1
drivers/usb/host/Makefile
drivers/usb/host/Makefile
+1
-1
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-dbg.c
+10
-7
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hcd.c
+2
-2
drivers/usb/host/ehci-mem.c
drivers/usb/host/ehci-mem.c
+28
-13
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-q.c
+45
-41
drivers/usb/host/ehci.h
drivers/usb/host/ehci.h
+1
-5
drivers/usb/image/scanner.c
drivers/usb/image/scanner.c
+5
-5
drivers/usb/image/scanner.h
drivers/usb/image/scanner.h
+4
-4
drivers/usb/media/vicam.c
drivers/usb/media/vicam.c
+0
-1
drivers/usb/misc/usbtest.c
drivers/usb/misc/usbtest.c
+99
-8
drivers/usb/net/Kconfig
drivers/usb/net/Kconfig
+9
-6
drivers/usb/storage/freecom.c
drivers/usb/storage/freecom.c
+2
-50
drivers/usb/storage/isd200.c
drivers/usb/storage/isd200.c
+37
-168
drivers/usb/storage/raw_bulk.c
drivers/usb/storage/raw_bulk.c
+2
-9
drivers/usb/storage/scsiglue.c
drivers/usb/storage/scsiglue.c
+1
-1
drivers/usb/storage/transport.c
drivers/usb/storage/transport.c
+9
-70
drivers/usb/storage/transport.h
drivers/usb/storage/transport.h
+0
-1
drivers/usb/storage/usb.c
drivers/usb/storage/usb.c
+0
-35
include/linux/device.h
include/linux/device.h
+5
-5
include/linux/kernel.h
include/linux/kernel.h
+1
-1
No files found.
drivers/usb/Makefile
View file @
89f0f973
...
...
@@ -8,13 +8,8 @@ obj-$(CONFIG_USB) += core/
obj-$(CONFIG_USB_EHCI_HCD)
+=
host/
obj-$(CONFIG_USB_OHCI_HCD)
+=
host/
obj-$(CONFIG_USB_OHCI)
+=
host/
obj-$(CONFIG_USB_OHCI_SA1111)
+=
host/
obj-$(CONFIG_USB_SL811HS)
+=
host/
obj-$(CONFIG_USB_UHCI_ALT)
+=
host/
obj-$(CONFIG_USB_UHCI_HCD_ALT)
+=
host/
obj-$(CONFIG_USB_UHCI_HCD)
+=
host/
obj-$(CONFIG_USB_
UHCI)
+=
host/
obj-$(CONFIG_USB_
SL811HS)
+=
host/
obj-$(CONFIG_USB_ACM)
+=
class/
obj-$(CONFIG_USB_AUDIO)
+=
class/
...
...
drivers/usb/class/Kconfig
View file @
89f0f973
...
...
@@ -20,14 +20,16 @@ config USB_BLUETOOTH_TTY
tristate "USB Bluetooth TTY support"
depends on USB
---help---
Say Y here if you want to connect a USB Bluetooth device to your
computer's USB port. You will need the Bluetooth stack (available
at <http://developer.axis.com/software/index.shtml>) to fully use
the device.
This driver implements a tty inteface to a Bluetooth device. If
you want to use a socket based Bluetooth stack (like the BlueZ
stack), do not use this driver.
This driver implements a nonstandard tty interface to a Bluetooth
device that can be used only by specialized Bluetooth HCI software.
Say Y here if you want to use OpenBT Bluetooth stack (available
at <http://developer.axis.com/software/index.shtml>), or other TTY
based Bluetooth stacks, and want to connect a USB Bluetooth device
to your computer's USB port.
Do *not* enable this driver if you want to use generic Linux
Bluetooth support.
If in doubt, say N here.
...
...
drivers/usb/class/usblp.c
View file @
89f0f973
/*
* usblp.c Version 0.1
2
* usblp.c Version 0.1
3
*
* Copyright (c) 1999 Michael Gee <michael@linuxspecific.com>
* Copyright (c) 1999 Pavel Machek <pavel@suse.cz>
* Copyright (c) 2000 Randy Dunlap <r
andy.dunlap@intel.com
>
* Copyright (c) 2000 Randy Dunlap <r
ddunlap@osdl.org
>
* Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz>
# Copyright (c) 2001 Pete Zaitcev <zaitcev@redhat.com>
# Copyright (c) 2001 David Paschal <paschal@rcsis.com>
...
...
@@ -25,6 +25,8 @@
* v0.10- remove sleep_on, fix error on oom (oliver@neukum.org)
* v0.11 - add proto_bias option (Pete Zaitcev)
* v0.12 - add hpoj.sourceforge.net ioctls (David Paschal)
* v0.13 - alloc space for statusbuf (<status> not on stack);
* use usb_buffer_alloc() for read buf & write buf;
*/
/*
...
...
@@ -59,7 +61,7 @@
/*
* Version Information
*/
#define DRIVER_VERSION "v0.1
2
"
#define DRIVER_VERSION "v0.1
3
"
#define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap, Pete Zaitcev, David Paschal"
#define DRIVER_DESC "USB Printer Device Class driver"
...
...
@@ -120,11 +122,19 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H
#define USBLP_LAST_PROTOCOL 3
#define USBLP_MAX_PROTOCOLS (USBLP_LAST_PROTOCOL+1)
/*
* some arbitrary status buffer size;
* need a status buffer that is allocated via kmalloc(), not on stack
*/
#define STATUS_BUF_SIZE 8
struct
usblp
{
struct
usb_device
*
dev
;
/* USB device */
devfs_handle_t
devfs
;
/* devfs device */
struct
semaphore
sem
;
/* locks this struct, especially "dev" */
char
*
buf
;
/* writeurb->transfer_buffer */
char
*
writebuf
;
/* write transfer_buffer */
char
*
readbuf
;
/* read transfer_buffer */
char
*
statusbuf
;
/* status transfer_buffer */
struct
urb
*
readurb
,
*
writeurb
;
/* The urbs */
wait_queue_head_t
wait
;
/* Zzzzz ... */
int
readcount
;
/* Counter for reads */
...
...
@@ -289,13 +299,14 @@ static int usblp_check_status(struct usblp *usblp, int err)
unsigned
char
status
,
newerr
=
0
;
int
error
;
error
=
usblp_read_status
(
usblp
,
&
status
);
error
=
usblp_read_status
(
usblp
,
usblp
->
statusbuf
);
if
(
error
<
0
)
{
err
(
"usblp%d: error %d reading printer status"
,
usblp
->
minor
,
error
);
return
0
;
}
status
=
*
usblp
->
statusbuf
;
if
(
~
status
&
LP_PERRORP
)
{
newerr
=
3
;
if
(
status
&
LP_POUTPA
)
newerr
=
1
;
...
...
@@ -375,8 +386,12 @@ static void usblp_cleanup (struct usblp *usblp)
usb_deregister_dev
(
1
,
usblp
->
minor
);
info
(
"usblp%d: removed"
,
usblp
->
minor
);
kfree
(
usblp
->
writeurb
->
transfer_buffer
);
usb_buffer_free
(
usblp
->
dev
,
USBLP_BUF_SIZE
,
usblp
->
writebuf
,
usblp
->
writeurb
->
transfer_dma
);
usb_buffer_free
(
usblp
->
dev
,
USBLP_BUF_SIZE
,
usblp
->
readbuf
,
usblp
->
writeurb
->
transfer_dma
);
kfree
(
usblp
->
device_id_string
);
kfree
(
usblp
->
statusbuf
);
usb_free_urb
(
usblp
->
writeurb
);
usb_free_urb
(
usblp
->
readurb
);
kfree
(
usblp
);
...
...
@@ -841,11 +856,27 @@ static int usblp_probe(struct usb_interface *intf,
goto
abort_minor
;
}
/* Malloc write/read buffers in one chunk. We somewhat wastefully
usblp
->
writebuf
=
usblp
->
readbuf
=
NULL
;
usblp
->
writeurb
->
transfer_flags
=
URB_NO_DMA_MAP
;
usblp
->
readurb
->
transfer_flags
=
URB_NO_DMA_MAP
;
/* Malloc write & read buffers. We somewhat wastefully
* malloc both regardless of bidirectionality, because the
* alternate setting can be changed later via an ioctl. */
if
(
!
(
usblp
->
buf
=
kmalloc
(
2
*
USBLP_BUF_SIZE
,
GFP_KERNEL
)))
{
err
(
"out of memory for buf"
);
if
(
!
(
usblp
->
writebuf
=
usb_buffer_alloc
(
dev
,
USBLP_BUF_SIZE
,
GFP_KERNEL
,
&
usblp
->
writeurb
->
transfer_dma
)))
{
err
(
"out of memory for write buf"
);
goto
abort_minor
;
}
if
(
!
(
usblp
->
readbuf
=
usb_buffer_alloc
(
dev
,
USBLP_BUF_SIZE
,
GFP_KERNEL
,
&
usblp
->
readurb
->
transfer_dma
)))
{
err
(
"out of memory for read buf"
);
goto
abort_minor
;
}
/* Allocate buffer for printer status */
usblp
->
statusbuf
=
kmalloc
(
STATUS_BUF_SIZE
,
GFP_KERNEL
);
if
(
!
usblp
->
statusbuf
)
{
err
(
"out of memory for statusbuf"
);
goto
abort_minor
;
}
...
...
@@ -900,10 +931,16 @@ static int usblp_probe(struct usb_interface *intf,
usb_deregister_dev
(
1
,
usblp
->
minor
);
abort:
if
(
usblp
)
{
if
(
usblp
->
writebuf
)
usb_buffer_free
(
usblp
->
dev
,
USBLP_BUF_SIZE
,
usblp
->
writebuf
,
usblp
->
writeurb
->
transfer_dma
);
if
(
usblp
->
readbuf
)
usb_buffer_free
(
usblp
->
dev
,
USBLP_BUF_SIZE
,
usblp
->
readbuf
,
usblp
->
writeurb
->
transfer_dma
);
if
(
usblp
->
statusbuf
)
kfree
(
usblp
->
statusbuf
);
if
(
usblp
->
device_id_string
)
kfree
(
usblp
->
device_id_string
);
usb_free_urb
(
usblp
->
writeurb
);
usb_free_urb
(
usblp
->
readurb
);
if
(
usblp
->
buf
)
kfree
(
usblp
->
buf
);
if
(
usblp
->
device_id_string
)
kfree
(
usblp
->
device_id_string
);
kfree
(
usblp
);
}
return
-
EIO
;
...
...
@@ -1020,16 +1057,16 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
usb_fill_bulk_urb
(
usblp
->
writeurb
,
usblp
->
dev
,
usb_sndbulkpipe
(
usblp
->
dev
,
usblp
->
protocol
[
protocol
].
epwrite
->
bEndpointAddress
),
usblp
->
buf
,
0
,
usblp
->
protocol
[
protocol
].
epwrite
->
bEndpointAddress
),
usblp
->
write
buf
,
0
,
usblp_bulk_write
,
usblp
);
usblp
->
bidir
=
(
usblp
->
protocol
[
protocol
].
epread
!=
0
);
if
(
usblp
->
bidir
)
usb_fill_bulk_urb
(
usblp
->
readurb
,
usblp
->
dev
,
usb_rcvbulkpipe
(
usblp
->
dev
,
usblp
->
protocol
[
protocol
].
epread
->
bEndpointAddress
),
usblp
->
buf
+
USBLP_BUF_SIZE
,
USBLP_BUF_SIZE
,
usblp
->
protocol
[
protocol
].
epread
->
bEndpointAddress
),
usblp
->
readbuf
,
USBLP_BUF_SIZE
,
usblp_bulk_read
,
usblp
);
usblp
->
current_protocol
=
protocol
;
...
...
drivers/usb/core/driverfs.c
View file @
89f0f973
...
...
@@ -148,23 +148,31 @@ usb_descriptor_attr (bcdDevice, "%04x\n")
usb_descriptor_attr
(
bDeviceClass
,
"%02x
\n
"
)
usb_descriptor_attr
(
bDeviceSubClass
,
"%02x
\n
"
)
usb_descriptor_attr
(
bDeviceProtocol
,
"%02x
\n
"
)
usb_descriptor_attr
(
bNumConfigurations
,
"%d
\n
"
)
void
usb_create_driverfs_dev_files
(
struct
usb_device
*
udev
)
{
struct
device
*
dev
=
&
udev
->
dev
;
/* current configuration's attributes */
device_create_file
(
dev
,
&
dev_attr_bNumInterfaces
);
device_create_file
(
dev
,
&
dev_attr_bConfigurationValue
);
device_create_file
(
dev
,
&
dev_attr_bmAttributes
);
device_create_file
(
dev
,
&
dev_attr_bMaxPower
);
/* device attributes */
device_create_file
(
dev
,
&
dev_attr_idVendor
);
device_create_file
(
dev
,
&
dev_attr_idProduct
);
device_create_file
(
dev
,
&
dev_attr_bcdDevice
);
device_create_file
(
dev
,
&
dev_attr_bDeviceClass
);
device_create_file
(
dev
,
&
dev_attr_bDeviceSubClass
);
device_create_file
(
dev
,
&
dev_attr_bDeviceProtocol
);
device_create_file
(
dev
,
&
dev_attr_bNumConfigurations
);
/* speed varies depending on how you connect the device */
device_create_file
(
dev
,
&
dev_attr_speed
);
// FIXME iff there are other speed configs, show how many
if
(
udev
->
descriptor
.
iManufacturer
)
device_create_file
(
dev
,
&
dev_attr_manufacturer
);
...
...
drivers/usb/core/hcd.c
View file @
89f0f973
...
...
@@ -23,6 +23,11 @@
*/
#include <linux/config.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#endif
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
...
...
@@ -32,13 +37,6 @@
#include <linux/pci.h>
/* for hcd->pdev and dma addressing */
#include <asm/byteorder.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/usb.h>
#include "hcd.h"
...
...
@@ -1090,6 +1088,7 @@ static int hcd_unlink_urb (struct urb *urb)
{
struct
hcd_dev
*
dev
;
struct
usb_hcd
*
hcd
=
0
;
struct
device
*
sys
=
0
;
unsigned
long
flags
;
struct
completion_splice
splice
;
int
retval
;
...
...
@@ -1110,38 +1109,31 @@ static int hcd_unlink_urb (struct urb *urb)
*/
spin_lock_irqsave
(
&
urb
->
lock
,
flags
);
spin_lock
(
&
hcd_data_lock
);
if
(
!
urb
->
hcpriv
||
urb
->
transfer_flags
&
URB_TIMEOUT_KILLED
)
{
retval
=
-
EINVAL
;
goto
done
;
}
if
(
!
urb
->
dev
||
!
urb
->
dev
->
bus
)
{
retval
=
-
ENODEV
;
goto
done
;
}
/* giveback clears dev; non-null means it's linked at this level */
dev
=
urb
->
dev
->
hcpriv
;
sys
=
&
urb
->
dev
->
dev
;
hcd
=
urb
->
dev
->
bus
->
hcpriv
;
if
(
!
dev
||
!
hcd
)
{
retval
=
-
ENODEV
;
goto
done
;
}
/* Except for interrupt transfers, any status except -EINPROGRESS
* means the HCD already started to unlink this URB from the hardware.
* So there's no more work to do.
*
* For interrupt transfers, this is the only way to trigger unlinking
* from the hardware. Since we (currently) overload urb->status to
* tell the driver to unlink, error status might get clobbered ...
* unless that transfer hasn't yet restarted. One such case is when
* the URB gets unlinked from its completion handler.
if
(
!
urb
->
hcpriv
)
{
retval
=
-
EINVAL
;
goto
done
;
}
/* Any status except -EINPROGRESS means something already started to
* unlink this URB from the hardware. So there's no more work to do.
*
* FIXME use
an URB_UNLINKED flag to match URB_TIMEOUT_KILLED
* FIXME use
better explicit urb state
*/
if
(
urb
->
status
!=
-
EINPROGRESS
&&
usb_pipetype
(
urb
->
pipe
)
!=
PIPE_INTERRUPT
)
{
if
(
urb
->
status
!=
-
EINPROGRESS
)
{
retval
=
-
EINVAL
;
goto
done
;
}
...
...
@@ -1150,9 +1142,7 @@ static int hcd_unlink_urb (struct urb *urb)
* lower level hcd code is always async, locking on urb->status
* updates; an intercepted completion unblocks us.
*/
if
((
urb
->
transfer_flags
&
URB_TIMEOUT_KILLED
))
urb
->
status
=
-
ETIMEDOUT
;
else
if
(
!
(
urb
->
transfer_flags
&
URB_ASYNC_UNLINK
))
{
if
(
!
(
urb
->
transfer_flags
&
URB_ASYNC_UNLINK
))
{
if
(
in_interrupt
())
{
dbg
(
"non-async unlink in_interrupt"
);
retval
=
-
EWOULDBLOCK
;
...
...
@@ -1177,29 +1167,34 @@ static int hcd_unlink_urb (struct urb *urb)
retval
=
0
;
}
else
{
retval
=
hcd
->
driver
->
urb_dequeue
(
hcd
,
urb
);
// FIXME: if retval and we tried to splice, whoa!!
if
(
retval
&&
urb
->
status
==
-
ENOENT
)
err
(
"whoa! retval %d"
,
retval
);
/* hcds shouldn't really fail these calls, but... */
if
(
retval
)
{
dev_dbg
(
*
sys
,
"dequeue %p --> %d
\n
"
,
urb
,
retval
);
if
(
!
(
urb
->
transfer_flags
&
URB_ASYNC_UNLINK
))
{
spin_lock_irqsave
(
&
urb
->
lock
,
flags
);
urb
->
complete
=
splice
.
complete
;
urb
->
context
=
splice
.
context
;
spin_unlock_irqrestore
(
&
urb
->
lock
,
flags
);
}
goto
bye
;
}
}
/* block till giveback, if needed */
if
(
!
(
urb
->
transfer_flags
&
(
URB_ASYNC_UNLINK
|
URB_TIMEOUT_KILLED
))
&&
HCD_IS_RUNNING
(
hcd
->
state
)
&&
!
retval
)
{
dbg
(
"%s: wait for giveback urb %p"
,
hcd
->
self
.
bus_name
,
urb
);
wait_for_completion
(
&
splice
.
done
);
}
else
if
((
urb
->
transfer_flags
&
URB_ASYNC_UNLINK
)
&&
retval
==
0
)
{
if
(
urb
->
transfer_flags
&
URB_ASYNC_UNLINK
)
return
-
EINPROGRESS
;
}
goto
bye
;
dev_dbg
(
*
sys
,
"wait for giveback urb %p
\n
"
,
urb
);
wait_for_completion
(
&
splice
.
done
);
return
0
;
done:
spin_unlock
(
&
hcd_data_lock
);
spin_unlock_irqrestore
(
&
urb
->
lock
,
flags
);
bye:
if
(
retval
)
dbg
(
"%s: hcd_unlink_urb fail %d"
,
hcd
?
hcd
->
self
.
bus_name
:
"(no bus?)"
,
retval
);
if
(
retval
&&
sys
)
dev_dbg
(
*
sys
,
"hcd_unlink_urb %p fail %d
\n
"
,
urb
,
retval
);
return
retval
;
}
...
...
drivers/usb/core/usb.c
View file @
89f0f973
...
...
@@ -67,7 +67,7 @@ static void generic_release (struct device_driver * drv)
}
static
struct
device_driver
usb_generic_driver
=
{
.
name
=
"
generic
"
,
.
name
=
"
usb
"
,
.
bus
=
&
usb_bus_type
,
.
probe
=
generic_probe
,
.
remove
=
generic_remove
,
...
...
@@ -514,17 +514,10 @@ static int usb_device_match (struct device *dev, struct device_driver *drv)
* or other modules, configure the device, and more. Drivers can provide
* a MODULE_DEVICE_TABLE to help with module loading subtasks.
*
* Some synchronization is important: removes can't start processing
* before the add-device processing completes, and vice versa. That keeps
* a stack of USB-related identifiers stable while they're in use. If we
* know that agents won't complete after they return (such as by forking
* a process that completes later), it's enough to just waitpid() for the
* agent -- as is currently done.
*
* The reason: we know we're called either from khubd (the typical case)
* or from root hub initialization (init, kapmd, modprobe, etc). In both
* cases, we know no other thread can recycle our address, since we must
* already have been serialized enough to prevent that.
* We're called either from khubd (the typical case) or from root hub
* (init, kapmd, modprobe, rmmod, etc), but the agents need to handle
* delays in event delivery. Use sysfs (and DEVPATH) to make sure the
* device (and this configuration!) are still present.
*/
static
int
usb_hotplug
(
struct
device
*
dev
,
char
**
envp
,
int
num_envp
,
char
*
buffer
,
int
buffer_size
)
...
...
@@ -579,7 +572,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
scratch
+=
length
;
#endif
/* per-device configuration
hack
s are common */
/* per-device configurations are common */
envp
[
i
++
]
=
scratch
;
length
+=
snprintf
(
scratch
,
buffer_size
-
length
,
"PRODUCT=%x/%x/%x"
,
usb_dev
->
descriptor
.
idVendor
,
...
...
@@ -604,10 +597,9 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
if
(
usb_dev
->
descriptor
.
bDeviceClass
==
0
)
{
int
alt
=
intf
->
act_altsetting
;
/* a simple/common case: one config, one interface, one driver
* with current altsetting being a reasonable setting.
* everything needs a smart agent and usbfs; or can rely on
* device-specific binding policies.
/* 2.4 only exposed interface zero. in 2.5, hotplug
* agents are called for all interfaces, and can use
* $DEVPATH/bInterfaceNumber if necessary.
*/
envp
[
i
++
]
=
scratch
;
length
+=
snprintf
(
scratch
,
buffer_size
-
length
,
...
...
@@ -949,6 +941,24 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
int
i
;
int
j
;
/*
* Set the driver for the usb device to point to the "generic" driver.
* This prevents the main usb device from being sent to the usb bus
* probe function. Yes, it's a hack, but a nice one :)
*
* Do it asap, so more driver model stuff (like the device.h message
* utilities) can be used in hcd submit/unlink code paths.
*/
usb_generic_driver
.
bus
=
&
usb_bus_type
;
dev
->
dev
.
parent
=
parent
;
dev
->
dev
.
driver
=
&
usb_generic_driver
;
dev
->
dev
.
bus
=
&
usb_bus_type
;
if
(
dev
->
dev
.
bus_id
[
0
]
==
0
)
sprintf
(
&
dev
->
dev
.
bus_id
[
0
],
"%d-%s"
,
dev
->
bus
->
busnum
,
dev
->
devpath
);
/* USB device state == default ... it's not usable yet */
/* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
* it's fixed size except for full speed devices.
*/
...
...
@@ -1010,6 +1020,8 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
dev
->
epmaxpacketout
[
0
]
=
dev
->
descriptor
.
bMaxPacketSize0
;
}
/* USB device state == addressed ... still not usable */
err
=
usb_get_device_descriptor
(
dev
);
if
(
err
<
(
signed
)
sizeof
(
dev
->
descriptor
))
{
if
(
err
<
0
)
...
...
@@ -1042,6 +1054,8 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
return
1
;
}
/* USB device state == configured ... tell the world! */
dbg
(
"new device strings: Mfr=%d, Product=%d, SerialNumber=%d"
,
dev
->
descriptor
.
iManufacturer
,
dev
->
descriptor
.
iProduct
,
dev
->
descriptor
.
iSerialNumber
);
set_device_description
(
dev
);
...
...
@@ -1051,23 +1065,10 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
usb_show_string
(
dev
,
"SerialNumber"
,
dev
->
descriptor
.
iSerialNumber
);
#endif
/*
* Set the driver for the usb device to point to the "generic" driver.
* This prevents the main usb device from being sent to the usb bus
* probe function. Yes, it's a hack, but a nice one :)
*/
usb_generic_driver
.
bus
=
&
usb_bus_type
;
dev
->
dev
.
parent
=
parent
;
dev
->
dev
.
driver
=
&
usb_generic_driver
;
dev
->
dev
.
bus
=
&
usb_bus_type
;
if
(
dev
->
dev
.
bus_id
[
0
]
==
0
)
sprintf
(
&
dev
->
dev
.
bus_id
[
0
],
"%d-%s"
,
dev
->
bus
->
busnum
,
dev
->
devpath
);
/* put into sysfs, with device and config specific files */
err
=
device_register
(
&
dev
->
dev
);
if
(
err
)
return
err
;
/* add the USB device specific driverfs files */
usb_create_driverfs_dev_files
(
dev
);
/* Register all of the interfaces for this device with the driver core.
...
...
drivers/usb/host/Kconfig
View file @
89f0f973
...
...
@@ -49,7 +49,7 @@ config USB_OHCI_HCD
The module will be called ohci-hcd.o. If you want to compile it
as a module, say M here and read <file:Documentation/modules.txt>.
config USB_UHCI_HCD
_ALT
config USB_UHCI_HCD
tristate "UHCI HCD (most Intel and VIA) support"
depends on USB
---help---
...
...
drivers/usb/host/Makefile
View file @
89f0f973
...
...
@@ -5,7 +5,7 @@
obj-$(CONFIG_USB_EHCI_HCD)
+=
ehci-hcd.o
obj-$(CONFIG_USB_OHCI_HCD)
+=
ohci-hcd.o
obj-$(CONFIG_USB_UHCI_HCD
_ALT
)
+=
uhci-hcd.o
obj-$(CONFIG_USB_UHCI_HCD)
+=
uhci-hcd.o
obj-$(CONFIG_USB_SL811HS)
+=
hc_sl811.o
...
...
drivers/usb/host/ehci-dbg.c
View file @
89f0f973
...
...
@@ -272,6 +272,7 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { }
static
void
qh_lines
(
struct
ehci_qh
*
qh
,
char
**
nextp
,
unsigned
*
sizep
)
{
u32
scratch
;
u32
hw_curr
;
struct
list_head
*
entry
;
struct
ehci_qtd
*
td
;
unsigned
temp
;
...
...
@@ -279,20 +280,22 @@ static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep)
char
*
next
=
*
nextp
;
scratch
=
cpu_to_le32p
(
&
qh
->
hw_info1
);
temp
=
snprintf
(
next
,
size
,
"qh/%p dev%d %cs ep%d %08x %08x"
,
hw_curr
=
cpu_to_le32p
(
&
qh
->
hw_current
);
temp
=
snprintf
(
next
,
size
,
"qh/%p dev%d %cs ep%d %08x %08x (%08x %08x)"
,
qh
,
scratch
&
0x007f
,
speed_char
(
scratch
),
(
scratch
>>
8
)
&
0x000f
,
scratch
,
cpu_to_le32p
(
&
qh
->
hw_info2
));
scratch
,
cpu_to_le32p
(
&
qh
->
hw_info2
),
hw_curr
,
cpu_to_le32p
(
&
qh
->
hw_token
));
size
-=
temp
;
next
+=
temp
;
list_for_each
(
entry
,
&
qh
->
qtd_list
)
{
td
=
list_entry
(
entry
,
struct
ehci_qtd
,
qtd_list
);
td
=
list_entry
(
entry
,
struct
ehci_qtd
,
qtd_list
);
scratch
=
cpu_to_le32p
(
&
td
->
hw_token
);
temp
=
snprintf
(
next
,
size
,
"
\n\t
td/%p %s len=%d %08x urb %p"
,
"
\n\t
%std/%p %s len=%d %08x urb %p"
,
(
hw_curr
==
td
->
qtd_dma
)
?
"*"
:
""
,
td
,
({
char
*
tmp
;
switch
((
scratch
>>
8
)
&
0x03
)
{
case
0
:
tmp
=
"out"
;
break
;
...
...
@@ -552,8 +555,8 @@ show_registers (struct device *dev, char *buf, size_t count, loff_t off)
size
-=
temp
;
next
+=
temp
;
temp
=
snprintf
(
next
,
size
,
"complete %ld unlink %ld
qpatch %ld
\n
"
,
ehci
->
stats
.
complete
,
ehci
->
stats
.
unlink
,
ehci
->
stats
.
qpatch
);
temp
=
snprintf
(
next
,
size
,
"complete %ld unlink %ld
\n
"
,
ehci
->
stats
.
complete
,
ehci
->
stats
.
unlink
);
size
-=
temp
;
next
+=
temp
;
#endif
...
...
drivers/usb/host/ehci-hcd.c
View file @
89f0f973
...
...
@@ -494,8 +494,8 @@ static void ehci_stop (struct usb_hcd *hcd)
#ifdef EHCI_STATS
dbg
(
"irq normal %ld err %ld reclaim %ld"
,
ehci
->
stats
.
normal
,
ehci
->
stats
.
error
,
ehci
->
stats
.
reclaim
);
dbg
(
"complete %ld unlink %ld
qpatch %ld
"
,
ehci
->
stats
.
complete
,
ehci
->
stats
.
unlink
,
ehci
->
stats
.
qpatch
);
dbg
(
"complete %ld unlink %ld"
,
ehci
->
stats
.
complete
,
ehci
->
stats
.
unlink
);
#endif
dbg_status
(
ehci
,
"ehci_stop completed"
,
readl
(
&
ehci
->
regs
->
status
));
...
...
drivers/usb/host/ehci-mem.c
View file @
89f0f973
...
...
@@ -58,19 +58,23 @@ static void ehci_hcd_free (struct usb_hcd *hcd)
/* Allocate the key transfer structures from the previously allocated pool */
static
void
ehci_qtd_init
(
struct
ehci_qtd
*
qtd
,
dma_addr_t
dma
)
{
memset
(
qtd
,
0
,
sizeof
*
qtd
);
qtd
->
qtd_dma
=
dma
;
qtd
->
hw_next
=
EHCI_LIST_END
;
qtd
->
hw_alt_next
=
EHCI_LIST_END
;
INIT_LIST_HEAD
(
&
qtd
->
qtd_list
);
}
static
struct
ehci_qtd
*
ehci_qtd_alloc
(
struct
ehci_hcd
*
ehci
,
int
flags
)
{
struct
ehci_qtd
*
qtd
;
dma_addr_t
dma
;
qtd
=
pci_pool_alloc
(
ehci
->
qtd_pool
,
flags
,
&
dma
);
if
(
qtd
!=
0
)
{
memset
(
qtd
,
0
,
sizeof
*
qtd
);
qtd
->
qtd_dma
=
dma
;
qtd
->
hw_next
=
EHCI_LIST_END
;
qtd
->
hw_alt_next
=
EHCI_LIST_END
;
INIT_LIST_HEAD
(
&
qtd
->
qtd_list
);
}
if
(
qtd
!=
0
)
ehci_qtd_init
(
qtd
,
dma
);
return
qtd
;
}
...
...
@@ -87,12 +91,21 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
qh
=
(
struct
ehci_qh
*
)
pci_pool_alloc
(
ehci
->
qh_pool
,
flags
,
&
dma
);
if
(
qh
)
{
memset
(
qh
,
0
,
sizeof
*
qh
);
atomic_set
(
&
qh
->
refcount
,
1
);
qh
->
qh_dma
=
dma
;
// INIT_LIST_HEAD (&qh->qh_list);
INIT_LIST_HEAD
(
&
qh
->
qtd_list
);
if
(
!
qh
)
return
qh
;
memset
(
qh
,
0
,
sizeof
*
qh
);
atomic_set
(
&
qh
->
refcount
,
1
);
qh
->
qh_dma
=
dma
;
// INIT_LIST_HEAD (&qh->qh_list);
INIT_LIST_HEAD
(
&
qh
->
qtd_list
);
/* dummy td enables safe urb queuing */
qh
->
dummy
=
ehci_qtd_alloc
(
ehci
,
flags
);
if
(
qh
->
dummy
==
0
)
{
dbg
(
"no dummy td"
);
pci_pool_free
(
ehci
->
qh_pool
,
qh
,
qh
->
qh_dma
);
qh
=
0
;
}
return
qh
;
}
...
...
@@ -115,6 +128,8 @@ static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh)
dbg
(
"unused qh not empty!"
);
BUG
();
}
if
(
qh
->
dummy
)
ehci_qtd_free
(
ehci
,
qh
->
dummy
);
pci_pool_free
(
ehci
->
qh_pool
,
qh
,
qh
->
qh_dma
);
}
...
...
drivers/usb/host/ehci-q.c
View file @
89f0f973
...
...
@@ -85,7 +85,7 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token)
/* update halted (but potentially linked) qh */
static
inline
void
qh_update
(
struct
ehci_qh
*
qh
,
struct
ehci_qtd
*
qtd
)
static
void
qh_update
(
struct
ehci_qh
*
qh
,
struct
ehci_qtd
*
qtd
)
{
qh
->
hw_current
=
0
;
qh
->
hw_qtd_next
=
QTD_NEXT
(
qtd
->
qtd_dma
);
...
...
@@ -221,17 +221,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
struct
urb
*
urb
=
qtd
->
urb
;
u32
token
=
0
;
/* hc's on-chip qh overlay cache can overwrite our idea of
* next qtd ptrs, if we appended a qtd while the queue was
* advancing. (because we don't use dummy qtds.)
*/
if
(
cpu_to_le32
(
qtd
->
qtd_dma
)
==
qh
->
hw_current
&&
qtd
->
hw_next
!=
qh
->
hw_qtd_next
)
{
qh
->
hw_alt_next
=
qtd
->
hw_alt_next
;
qh
->
hw_qtd_next
=
qtd
->
hw_next
;
COUNT
(
ehci
->
stats
.
qpatch
);
}
/* clean up any state from previous QTD ...*/
if
(
last
)
{
if
(
likely
(
last
->
urb
!=
urb
))
{
...
...
@@ -495,8 +484,7 @@ qh_urb_transaction (
}
/* by default, enable interrupt on urb completion */
// ... do it always, unless we switch over to dummy qtds
// if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT)))
if
(
likely
(
!
(
urb
->
transfer_flags
&
URB_NO_INTERRUPT
)))
qtd
->
hw_token
|=
__constant_cpu_to_le32
(
QTD_IOC
);
return
head
;
...
...
@@ -661,8 +649,15 @@ ehci_qh_make (
/* initialize sw and hw queues with these qtds */
if
(
!
list_empty
(
qtd_list
))
{
struct
ehci_qtd
*
qtd
;
/* hc's list view ends with dummy td; we might update it */
qtd
=
list_entry
(
qtd_list
->
prev
,
struct
ehci_qtd
,
qtd_list
);
qtd
->
hw_next
=
QTD_NEXT
(
qh
->
dummy
->
qtd_dma
);
list_splice
(
qtd_list
,
&
qh
->
qtd_list
);
qh_update
(
qh
,
list_entry
(
qtd_list
->
next
,
struct
ehci_qtd
,
qtd_list
));
qtd
=
list_entry
(
qtd_list
->
next
,
struct
ehci_qtd
,
qtd_list
);
qh_update
(
qh
,
qtd
);
}
else
{
qh
->
hw_qtd_next
=
qh
->
hw_alt_next
=
EHCI_LIST_END
;
}
...
...
@@ -767,39 +762,48 @@ static struct ehci_qh *qh_append_tds (
/* append to tds already queued to this qh? */
if
(
unlikely
(
!
list_empty
(
&
qh
->
qtd_list
)
&&
qtd
))
{
struct
ehci_qtd
*
last_qtd
;
u32
hw_next
;
/* update the last qtd's "next" pointer */
// dbg_qh ("non-empty qh", ehci, qh);
last_qtd
=
list_entry
(
qh
->
qtd_list
.
prev
,
struct
ehci_qtd
*
dummy
;
dma_addr_t
dma
;
u32
token
;
/* to avoid racing the HC, use the dummy td instead of
* the first td of our list (becomes new dummy). both
* tds stay deactivated until we're done, when the
* HC is allowed to fetch the old dummy (4.10.2).
*/
token
=
qtd
->
hw_token
;
qtd
->
hw_token
=
0
;
dummy
=
qh
->
dummy
;
// dbg ("swap td %p with dummy %p", qtd, dummy);
dma
=
dummy
->
qtd_dma
;
*
dummy
=
*
qtd
;
dummy
->
qtd_dma
=
dma
;
list_del
(
&
qtd
->
qtd_list
);
list_add
(
&
dummy
->
qtd_list
,
qtd_list
);
ehci_qtd_init
(
qtd
,
qtd
->
qtd_dma
);
qh
->
dummy
=
qtd
;
/* hc must see the new dummy at list end */
qtd
=
list_entry
(
qh
->
qtd_list
.
prev
,
struct
ehci_qtd
,
qtd_list
);
hw_next
=
QTD_NEXT
(
qtd
->
qtd_dma
);
last_qtd
->
hw_next
=
hw_next
;
/* previous urb allows short rx? maybe optimize. */
if
(
!
(
last_qtd
->
urb
->
transfer_flags
&
URB_SHORT_NOT_OK
)
&&
(
epnum
&
0x10
))
{
// only the last QTD for now
last_qtd
->
hw_alt_next
=
hw_next
;
}
qtd
->
hw_next
=
QTD_NEXT
(
dma
);
/* qh_completions() may need to patch the qh overlay if
* the hc was advancing this queue while we appended.
* we know it can: last_qtd->hw_token has IOC set.
*
* or: use a dummy td (so the overlay gets the next td
* only when we set its active bit); fewer irqs.
*/
/* let the hc process these next qtds */
wmb
();
dummy
->
hw_token
=
token
;
/* no URB queued */
}
else
{
// dbg_qh ("empty qh", ehci, qh)
;
struct
ehci_qtd
*
last_qtd
;
/* NOTE: we already canceled any queued URBs
* when the endpoint halted.
*/
/* make sure hc sees current dummy at the end */
last_qtd
=
list_entry
(
qtd_list
->
prev
,
struct
ehci_qtd
,
qtd_list
);
last_qtd
->
hw_next
=
QTD_NEXT
(
qh
->
dummy
->
qtd_dma
);
// dbg_qh ("empty qh", ehci, qh);
/* usb_clear_halt() means qh data toggle gets reset */
if
(
unlikely
(
!
usb_gettoggle
(
urb
->
dev
,
...
...
drivers/usb/host/ehci.h
View file @
89f0f973
...
...
@@ -31,11 +31,6 @@ struct ehci_stats {
/* termination of urbs from core */
unsigned
long
complete
;
unsigned
long
unlink
;
/* qhs patched to recover from td queueing race
* (can avoid by using 'dummy td', allowing fewer irqs)
*/
unsigned
long
qpatch
;
};
/* ehci_hcd->lock guards shared data against other CPUs:
...
...
@@ -311,6 +306,7 @@ struct ehci_qh {
dma_addr_t
qh_dma
;
/* address of qh */
union
ehci_shadow
qh_next
;
/* ptr to qh; or periodic */
struct
list_head
qtd_list
;
/* sw qtd list */
struct
ehci_qtd
*
dummy
;
atomic_t
refcount
;
...
...
drivers/usb/image/scanner.c
View file @
89f0f973
...
...
@@ -840,7 +840,7 @@ probe_scanner(struct usb_interface *intf,
struct
usb_device
*
dev
=
interface_to_usbdev
(
intf
);
struct
scn_usb_data
*
scn
;
struct
usb_host_interface
*
interface
;
struct
usb_
host_endpoint
*
endpoint
;
struct
usb_
endpoint_descriptor
*
endpoint
;
int
ep_cnt
;
int
ix
;
...
...
@@ -911,7 +911,6 @@ probe_scanner(struct usb_interface *intf,
}
interface
=
intf
->
altsetting
;
endpoint
=
&
interface
->
endpoint
[
0
];
/*
* Start checking for two bulk endpoints OR two bulk endpoints *and* one
...
...
@@ -929,22 +928,23 @@ probe_scanner(struct usb_interface *intf,
ep_cnt
=
have_bulk_in
=
have_bulk_out
=
have_intr
=
0
;
while
(
ep_cnt
<
interface
->
desc
.
bNumEndpoints
)
{
endpoint
=
&
interface
->
endpoint
[
ep_cnt
].
desc
;
if
(
!
have_bulk_in
&&
IS_EP_BULK_IN
(
endpoint
[
ep_cnt
]
))
{
if
(
!
have_bulk_in
&&
IS_EP_BULK_IN
(
endpoint
))
{
ep_cnt
++
;
have_bulk_in
=
ep_cnt
;
dbg
(
"probe_scanner: bulk_in_ep:%d"
,
have_bulk_in
);
continue
;
}
if
(
!
have_bulk_out
&&
IS_EP_BULK_OUT
(
endpoint
[
ep_cnt
]
))
{
if
(
!
have_bulk_out
&&
IS_EP_BULK_OUT
(
endpoint
))
{
ep_cnt
++
;
have_bulk_out
=
ep_cnt
;
dbg
(
"probe_scanner: bulk_out_ep:%d"
,
have_bulk_out
);
continue
;
}
if
(
!
have_intr
&&
IS_EP_INTR
(
endpoint
[
ep_cnt
]
))
{
if
(
!
have_intr
&&
IS_EP_INTR
(
endpoint
))
{
ep_cnt
++
;
have_intr
=
ep_cnt
;
dbg
(
"probe_scanner: intr_ep:%d"
,
have_intr
);
...
...
drivers/usb/image/scanner.h
View file @
89f0f973
...
...
@@ -211,10 +211,10 @@ static struct usb_device_id scanner_device_ids [] = {
MODULE_DEVICE_TABLE
(
usb
,
scanner_device_ids
);
#define IS_EP_BULK(ep) ((ep)
.desc.
bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0)
#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep)
.desc.
bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep)
.desc.
bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
#define IS_EP_INTR(ep) ((ep)
.desc.
bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0)
#define IS_EP_BULK(ep) ((ep)
->
bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0)
#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep)
->
bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep)
->
bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
#define IS_EP_INTR(ep) ((ep)
->
bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0)
#define USB_SCN_MINOR(X) minor((X)->i_rdev) - SCN_BASE_MNR
...
...
drivers/usb/media/vicam.c
View file @
89f0f973
...
...
@@ -1214,7 +1214,6 @@ static struct video_device vicam_template = {
.
type
=
VID_TYPE_CAPTURE
,
.
hardware
=
VID_HARDWARE_VICAM
,
.
fops
=
&
vicam_fops
,
// .initialize = vicam_video_init,
.
minor
=
-
1
,
};
...
...
drivers/usb/misc/usbtest.c
View file @
89f0f973
...
...
@@ -550,6 +550,74 @@ static int ch9_postconfig (struct usbtest_dev *dev)
/*-------------------------------------------------------------------------*/
static
void
unlink1_callback
(
struct
urb
*
urb
)
{
int
status
=
urb
->
status
;
// we "know" -EPIPE (stall) never happens
if
(
!
status
)
status
=
usb_submit_urb
(
urb
,
SLAB_ATOMIC
);
if
(
status
)
{
if
(
status
==
-
ECONNRESET
||
status
==
-
ENOENT
)
status
=
0
;
urb
->
status
=
status
;
complete
((
struct
completion
*
)
urb
->
context
);
}
}
static
int
unlink1
(
struct
usbtest_dev
*
dev
,
int
pipe
,
int
size
,
int
async
)
{
struct
urb
*
urb
;
struct
completion
completion
;
int
retval
=
0
;
init_completion
(
&
completion
);
urb
=
simple_alloc_urb
(
testdev_to_usbdev
(
dev
),
pipe
,
size
);
if
(
async
)
urb
->
transfer_flags
|=
URB_ASYNC_UNLINK
;
urb
->
context
=
&
completion
;
urb
->
complete
=
unlink1_callback
;
/* keep the endpoint busy. there are lots of hc/hcd-internal
* states, and testing should get to all of them over time.
*
* FIXME want additional tests for when endpoint is STALLing
* due to errors, or is just NAKing requests.
*/
if
((
retval
=
usb_submit_urb
(
urb
,
SLAB_KERNEL
))
!=
0
)
{
dbg
(
"submit/unlink fail %d"
,
retval
);
return
retval
;
}
/* unlinking that should always work. variable delay tests more
* hcd states and code paths, even with little other system load.
*/
wait_ms
(
jiffies
%
(
2
*
INTERRUPT_RATE
));
retval
=
usb_unlink_urb
(
urb
);
if
(
!
(
retval
==
0
||
retval
==
-
EINPROGRESS
))
{
dbg
(
"submit/unlink fail %d"
,
retval
);
return
retval
;
}
wait_for_completion
(
&
completion
);
retval
=
urb
->
status
;
simple_free_urb
(
urb
);
return
retval
;
}
static
int
unlink_simple
(
struct
usbtest_dev
*
dev
,
int
pipe
,
int
len
)
{
int
retval
=
0
;
/* test sync and async paths */
retval
=
unlink1
(
dev
,
pipe
,
len
,
1
);
if
(
!
retval
)
retval
=
unlink1
(
dev
,
pipe
,
len
,
0
);
return
retval
;
}
/*-------------------------------------------------------------------------*/
/* We only have this one interface to user space, through usbfs.
* User mode code can scan usbfs to find N different devices (maybe on
* different busses) to use when testing, and allocate one thread per
...
...
@@ -560,7 +628,8 @@ static int ch9_postconfig (struct usbtest_dev *dev)
* video capture, and so on. Run different tests at different times, in
* different sequences. Nothing here should interact with other devices,
* except indirectly by consuming USB bandwidth and CPU resources for test
* threads and request completion.
* threads and request completion. But the only way to know that for sure
* is to test when HC queues are in use by many devices.
*/
static
int
...
...
@@ -761,13 +830,35 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
dbg
(
"ch9 subset failed, iterations left %d"
,
i
);
break
;
/* test cases for the unlink/cancel codepaths need a thread to
* usb_unlink_urb() or usg_sg_cancel(), and a way to check if
* the urb/sg_request was properly canceled.
*
* for the unlink-queued cases, the usb_sg_*() code uses/tests
* the "streamed" cleanup mode, not the "packet" one
*/
// case 10: queued control
/* simple non-queued unlinks (ring with one urb) */
case
11
:
if
(
dev
->
in_pipe
==
0
||
!
param
->
length
)
break
;
retval
=
0
;
dbg
(
"%s TEST 11: unlink %d reads of %d"
,
dev
->
id
,
param
->
iterations
,
param
->
length
);
for
(
i
=
param
->
iterations
;
retval
==
0
&&
i
--
;
/* NOP */
)
retval
=
unlink_simple
(
dev
,
dev
->
in_pipe
,
param
->
length
);
if
(
retval
)
dbg
(
"unlink reads failed, iterations left %d"
,
i
);
break
;
case
12
:
if
(
dev
->
out_pipe
==
0
||
!
param
->
length
)
break
;
retval
=
0
;
dbg
(
"%s TEST 12: unlink %d writes of %d"
,
dev
->
id
,
param
->
iterations
,
param
->
length
);
for
(
i
=
param
->
iterations
;
retval
==
0
&&
i
--
;
/* NOP */
)
retval
=
unlink_simple
(
dev
,
dev
->
out_pipe
,
param
->
length
);
if
(
retval
)
dbg
(
"unlink writes failed, iterations left %d"
,
i
);
break
;
// FIXME unlink from queue (ring with N urbs)
// FIXME scatterlist cancel (needs helper thread)
}
do_gettimeofday
(
&
param
->
duration
);
...
...
drivers/usb/net/Kconfig
View file @
89f0f973
...
...
@@ -124,20 +124,23 @@ config USB_RTL8150
module, say M here and read <file:Documentation/modules.txt>.
config USB_USBNET
tristate "USB-to-USB Networking
cable device support
"
tristate "USB-to-USB Networking
for cables, PDAs and other devices
"
depends on USB && NET
---help---
This driver supports network links over USB with USB "Network"
or "data transfer" cables, often used to network laptops to PCs.
Such cables have chips from suppliers such as Belkin/eTEK, GeneSys
(GeneLink), NetChip and Prolific. Intelligent USB devices could also
use this approach to provide Internet access, using standard USB
cabling. You can find these chips also on some motherboards with
USB PC2PC support.
(GeneLink), NetChip and Prolific. Some motherboards with USB PC2PC
support include such chips.
Intelligent USB devices, such as PDAs running Linux (like Yopy
and Zaurus, or iPaqs after upgrading to Linux) can use the same
approach to provide Internet access.
These links will have names like "usb0", "usb1", etc. They act
like two-node Ethernets, so you can use 802.1d Ethernet Bridging
(CONFIG_BRIDGE) to simplify your network routing.
(CONFIG_BRIDGE) to simplify your network routing. For more
information see <http://www.linux-usb.org/usbnet/>.
This code is also available as a kernel module (code which can be
inserted in and removed from the running kernel whenever you want).
...
...
drivers/usb/storage/freecom.c
View file @
89f0f973
...
...
@@ -128,15 +128,8 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
result
=
usb_stor_bulk_msg
(
us
,
fxfr
,
opipe
,
FCM_PACKET_LENGTH
,
&
partial
);
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
US_DEBUGP
(
"Freecom readdata xpot failure: r=%d, p=%d
\n
"
,
US_DEBUGP
(
"Freecom readdata xpo
r
t failure: r=%d, p=%d
\n
"
,
result
,
partial
);
/* has the current command been aborted? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"freecom_readdata(): transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
return
USB_STOR_TRANSPORT_ERROR
;
}
US_DEBUGP
(
"Done issuing read request: %d %d
\n
"
,
result
,
partial
);
...
...
@@ -171,15 +164,8 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
result
=
usb_stor_bulk_msg
(
us
,
fxfr
,
opipe
,
FCM_PACKET_LENGTH
,
&
partial
);
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
US_DEBUGP
(
"Freecom writedata xpot failure: r=%d, p=%d
\n
"
,
US_DEBUGP
(
"Freecom writedata xpo
r
t failure: r=%d, p=%d
\n
"
,
result
,
partial
);
/* has the current command been aborted? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"freecom_writedata(): transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
return
USB_STOR_TRANSPORT_ERROR
;
}
US_DEBUGP
(
"Done issuing write request: %d %d
\n
"
,
...
...
@@ -238,13 +224,6 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
US_DEBUGP
(
"freecom xport failure: r=%d, p=%d
\n
"
,
result
,
partial
);
/* we canceled this transfer */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"freecom_transport(): transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
return
USB_STOR_TRANSPORT_ERROR
;
}
...
...
@@ -253,12 +232,6 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
result
=
usb_stor_bulk_msg
(
us
,
fst
,
ipipe
,
FCM_PACKET_LENGTH
,
&
partial
);
US_DEBUGP
(
"foo Status result %d %d
\n
"
,
result
,
partial
);
/* we canceled this transfer */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"freecom_transport(): transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
if
(
result
!=
USB_STOR_XFER_GOOD
)
return
USB_STOR_TRANSPORT_ERROR
;
...
...
@@ -293,13 +266,6 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
US_DEBUGP
(
"freecom xport failure: r=%d, p=%d
\n
"
,
result
,
partial
);
/* we canceled this transfer */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"freecom_transport(): transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
return
USB_STOR_TRANSPORT_ERROR
;
}
...
...
@@ -308,12 +274,6 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
FCM_PACKET_LENGTH
,
&
partial
);
US_DEBUGP
(
"bar Status result %d %d
\n
"
,
result
,
partial
);
/* we canceled this transfer */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"freecom_transport(): transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
if
(
result
>
USB_STOR_XFER_SHORT
)
return
USB_STOR_TRANSPORT_ERROR
;
...
...
@@ -372,10 +332,6 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
FCM_PACKET_LENGTH
,
&
partial
);
US_DEBUG
(
pdump
((
void
*
)
fst
,
partial
));
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"freecom_transport: transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
if
(
partial
!=
4
||
result
>
USB_STOR_XFER_SHORT
)
return
USB_STOR_TRANSPORT_ERROR
;
if
((
fst
->
Status
&
ERR_STAT
)
!=
0
)
{
...
...
@@ -401,10 +357,6 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
result
=
usb_stor_bulk_msg
(
us
,
fst
,
ipipe
,
FCM_PACKET_LENGTH
,
&
partial
);
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"freecom_transport: transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
if
(
partial
!=
4
||
result
>
USB_STOR_XFER_SHORT
)
return
USB_STOR_TRANSPORT_ERROR
;
if
((
fst
->
Status
&
ERR_STAT
)
!=
0
)
{
...
...
drivers/usb/storage/isd200.c
View file @
89f0f973
...
...
@@ -130,8 +130,6 @@
#define ISD200_TRANSPORT_GOOD 0
/* Transport good, command good */
#define ISD200_TRANSPORT_FAILED 1
/* Transport good, command failed */
#define ISD200_TRANSPORT_ERROR 2
/* Transport bad (i.e. device dead) */
#define ISD200_TRANSPORT_ABORTED 3
/* Transport aborted */
#define ISD200_TRANSPORT_SHORT 4
/* Transport short */
/* driver action codes */
#define ACTION_READ_STATUS 0
...
...
@@ -394,138 +392,6 @@ void isd200_build_sense(struct us_data *us, Scsi_Cmnd *srb)
***********************************************************************/
/**************************************************************************
* ISD200 Bulk Transport
*
* Note: This routine was copied from the usb_stor_Bulk_transport routine
* located in the transport.c source file. The scsi command is limited to
* only 12 bytes while the CDB for the ISD200 must be 16 bytes.
*/
int
isd200_Bulk_transport
(
struct
us_data
*
us
,
Scsi_Cmnd
*
srb
,
union
ata_cdb
*
AtaCdb
,
unsigned
char
AtaCdbLength
)
{
struct
bulk_cb_wrap
bcb
;
struct
bulk_cs_wrap
bcs
;
int
result
;
unsigned
int
transfer_length
;
int
dir
=
srb
->
sc_data_direction
;
srb
->
sc_data_direction
=
SCSI_DATA_WRITE
;
transfer_length
=
usb_stor_transfer_length
(
srb
);
srb
->
sc_data_direction
=
dir
;
/* set up the command wrapper */
bcb
.
Signature
=
cpu_to_le32
(
US_BULK_CB_SIGN
);
bcb
.
DataTransferLength
=
cpu_to_le32
(
transfer_length
);
bcb
.
Flags
=
srb
->
sc_data_direction
==
SCSI_DATA_READ
?
1
<<
7
:
0
;
bcb
.
Tag
=
srb
->
serial_number
;
bcb
.
Lun
=
srb
->
cmnd
[
1
]
>>
5
;
if
(
us
->
flags
&
US_FL_SCM_MULT_TARG
)
bcb
.
Lun
|=
srb
->
target
<<
4
;
bcb
.
Length
=
AtaCdbLength
;
/* copy the command payload */
memset
(
bcb
.
CDB
,
0
,
sizeof
(
bcb
.
CDB
));
memcpy
(
bcb
.
CDB
,
AtaCdb
,
bcb
.
Length
);
/* send it to out endpoint */
US_DEBUGP
(
"Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d
\n
"
,
le32_to_cpu
(
bcb
.
Signature
),
bcb
.
Tag
,
(
bcb
.
Lun
>>
4
),
(
bcb
.
Lun
&
0x0F
),
le32_to_cpu
(
bcb
.
DataTransferLength
),
bcb
.
Flags
,
bcb
.
Length
);
result
=
usb_stor_bulk_transfer_buf
(
us
,
us
->
send_bulk_pipe
,
(
char
*
)
&
bcb
,
US_BULK_CB_WRAP_LEN
,
NULL
);
US_DEBUGP
(
"Bulk command transfer result=%d
\n
"
,
result
);
/* did we abort this command? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
return
ISD200_TRANSPORT_ABORTED
;
}
if
(
result
!=
USB_STOR_XFER_GOOD
)
return
ISD200_TRANSPORT_ERROR
;
/* if the command transfered well, then we go to the data stage */
if
(
transfer_length
)
{
unsigned
int
pipe
=
srb
->
sc_data_direction
==
SCSI_DATA_READ
?
us
->
recv_bulk_pipe
:
us
->
send_bulk_pipe
;
result
=
usb_stor_bulk_transfer_srb
(
us
,
pipe
,
srb
,
transfer_length
);
US_DEBUGP
(
"Bulk data transfer result 0x%x
\n
"
,
result
);
/* if it was aborted, we need to indicate that */
if
(
result
==
USB_STOR_XFER_ABORTED
)
return
ISD200_TRANSPORT_ABORTED
;
if
(
result
==
USB_STOR_XFER_ERROR
)
return
ISD200_TRANSPORT_ERROR
;
}
/* See flow chart on pg 15 of the Bulk Only Transport spec for
* an explanation of how this code works.
*/
/* get CSW for device status */
US_DEBUGP
(
"Attempting to get CSW...
\n
"
);
result
=
usb_stor_bulk_transfer_buf
(
us
,
us
->
recv_bulk_pipe
,
(
char
*
)
&
bcs
,
US_BULK_CS_WRAP_LEN
,
NULL
);
/* did we abort this command? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
return
ISD200_TRANSPORT_ABORTED
;
}
/* did the attempt to read the CSW fail? */
if
(
result
==
USB_STOR_XFER_STALLED
)
{
/* get the status again */
US_DEBUGP
(
"Attempting to get CSW (2nd try)...
\n
"
);
result
=
usb_stor_bulk_transfer_buf
(
us
,
us
->
recv_bulk_pipe
,
(
char
*
)
&
bcs
,
US_BULK_CS_WRAP_LEN
,
NULL
);
/* if the command was aborted, indicate that */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
return
ISD200_TRANSPORT_ABORTED
;
}
}
/* if we still have a failure at this point, we're in trouble */
US_DEBUGP
(
"Bulk status result = %d
\n
"
,
result
);
if
(
result
!=
USB_STOR_XFER_GOOD
)
return
ISD200_TRANSPORT_ERROR
;
/* check bulk status */
US_DEBUGP
(
"Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x
\n
"
,
le32_to_cpu
(
bcs
.
Signature
),
bcs
.
Tag
,
bcs
.
Residue
,
bcs
.
Status
);
if
(
bcs
.
Signature
!=
cpu_to_le32
(
US_BULK_CS_SIGN
)
||
bcs
.
Tag
!=
bcb
.
Tag
||
bcs
.
Status
>
US_BULK_STAT_PHASE
)
{
US_DEBUGP
(
"Bulk logical error
\n
"
);
return
ISD200_TRANSPORT_ERROR
;
}
/* based on the status code, we report good or bad */
switch
(
bcs
.
Status
)
{
case
US_BULK_STAT_OK
:
/* command good -- note that we could be short on data */
if
(
srb
->
resid
>
0
)
return
ISD200_TRANSPORT_SHORT
;
return
ISD200_TRANSPORT_GOOD
;
case
US_BULK_STAT_FAIL
:
/* command failed */
return
ISD200_TRANSPORT_FAILED
;
case
US_BULK_STAT_PHASE
:
/* phase error */
usb_stor_Bulk_reset
(
us
);
return
ISD200_TRANSPORT_ERROR
;
}
/* we should never get here, but if we do, we're in trouble */
return
ISD200_TRANSPORT_ERROR
;
}
/**************************************************************************
* isd200_action
*
...
...
@@ -612,9 +478,11 @@ static int isd200_action( struct us_data *us, int action,
break
;
}
status
=
isd200_Bulk_transport
(
us
,
&
srb
,
&
ata
,
sizeof
(
ata
.
generic
));
if
(
status
!=
ISD200_TRANSPORT_GOOD
&&
status
!=
ISD200_TRANSPORT_SHORT
)
{
memcpy
(
srb
.
cmnd
,
&
ata
,
sizeof
(
ata
.
generic
));
status
=
usb_stor_Bulk_transport
(
&
srb
,
us
);
if
(
status
==
USB_STOR_TRANSPORT_GOOD
)
status
=
ISD200_GOOD
;
else
{
US_DEBUGP
(
" isd200_action(0x%02x) error: %d
\n
"
,
action
,
status
);
status
=
ISD200_ERROR
;
/* need to reset device here */
...
...
@@ -669,8 +537,8 @@ void isd200_invoke_transport( struct us_data *us,
/* send the command to the transport layer */
srb
->
resid
=
0
;
transferStatus
=
isd200_Bulk_transport
(
us
,
srb
,
ataCdb
,
sizeof
(
ataCdb
->
generic
)
);
memcpy
(
srb
->
cmnd
,
ataCdb
,
sizeof
(
ataCdb
->
generic
));
transferStatus
=
usb_stor_Bulk_transport
(
srb
,
us
);
/* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing
...
...
@@ -683,45 +551,37 @@ void isd200_invoke_transport( struct us_data *us,
switch
(
transferStatus
)
{
case
ISD200
_TRANSPORT_GOOD
:
case
USB_STOR
_TRANSPORT_GOOD
:
/* Indicate a good result */
srb
->
result
=
GOOD
<<
1
;
break
;
case
ISD200_TRANSPORT_ABORTED
:
/* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing
*/
US_DEBUGP
(
"-- transport indicates command was aborted
\n
"
);
srb
->
result
=
DID_ABORT
<<
16
;
break
;
case
ISD200_TRANSPORT_FAILED
:
case
USB_STOR_TRANSPORT_FAILED
:
US_DEBUGP
(
"-- transport indicates command failure
\n
"
);
need_auto_sense
=
1
;
break
;
case
ISD200
_TRANSPORT_ERROR
:
US_DEBUGP
(
"-- transport indicates transport
failure
\n
"
);
case
USB_STOR
_TRANSPORT_ERROR
:
US_DEBUGP
(
"-- transport indicates transport
error
\n
"
);
srb
->
result
=
DID_ERROR
<<
16
;
break
;
case
ISD200_TRANSPORT_SHORT
:
srb
->
result
=
GOOD
<<
1
;
if
(
!
((
srb
->
cmnd
[
0
]
==
REQUEST_SENSE
)
||
(
srb
->
cmnd
[
0
]
==
INQUIRY
)
||
(
srb
->
cmnd
[
0
]
==
MODE_SENSE
)
||
(
srb
->
cmnd
[
0
]
==
LOG_SENSE
)
||
(
srb
->
cmnd
[
0
]
==
MODE_SENSE_10
)))
{
US_DEBUGP
(
"-- unexpectedly short transfer
\n
"
);
need_auto_sense
=
1
;
}
break
;
/* Need reset here */
return
;
default:
US_DEBUGP
(
"-- transport indicates unknown
failure
\n
"
);
US_DEBUGP
(
"-- transport indicates unknown
error
\n
"
);
srb
->
result
=
DID_ERROR
<<
16
;
/* Need reset here */
return
;
}
if
((
srb
->
resid
>
0
)
&&
!
((
srb
->
cmnd
[
0
]
==
REQUEST_SENSE
)
||
(
srb
->
cmnd
[
0
]
==
INQUIRY
)
||
(
srb
->
cmnd
[
0
]
==
MODE_SENSE
)
||
(
srb
->
cmnd
[
0
]
==
LOG_SENSE
)
||
(
srb
->
cmnd
[
0
]
==
MODE_SENSE_10
)))
{
US_DEBUGP
(
"-- unexpectedly short transfer
\n
"
);
need_auto_sense
=
1
;
}
if
(
need_auto_sense
)
{
...
...
@@ -729,14 +589,23 @@ void isd200_invoke_transport( struct us_data *us,
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"-- auto-sense aborted
\n
"
);
srb
->
result
=
DID_ABORT
<<
16
;
}
else
if
(
result
==
ISD200_GOOD
)
return
;
}
if
(
result
==
ISD200_GOOD
)
{
isd200_build_sense
(
us
,
srb
);
srb
->
result
=
CHECK_CONDITION
<<
1
;
/* If things are really okay, then let's show that */
if
((
srb
->
sense_buffer
[
2
]
&
0xf
)
==
0x0
)
srb
->
result
=
GOOD
<<
1
;
}
else
srb
->
result
=
DID_ERROR
<<
16
;
}
/* Regardless of auto-sense, if we _know_ we have an error
* condition, show that in the result code
*/
if
(
transferStatus
==
ISD200
_TRANSPORT_FAILED
)
if
(
transferStatus
==
USB_STOR
_TRANSPORT_FAILED
)
srb
->
result
=
CHECK_CONDITION
<<
1
;
}
...
...
drivers/usb/storage/raw_bulk.c
View file @
89f0f973
/*
* Common routines for a handful of drivers.
* Unrelated to CF/SM - just USB stuff.
*
* This is mostly a thin layer on top of transport.c.
* It converts routines that return values like -EPIPE
* into routines that return USB_STOR_TRANSPORT_ABORTED etc.
*
* There is also some debug printing here.
* Unrelated to CF/SM - just scatter-gather stuff.
*/
#include "debug.h"
#include "transport.h"
#include "usb.h"
#include "raw_bulk.h"
/*
...
...
drivers/usb/storage/scsiglue.c
View file @
89f0f973
...
...
@@ -103,7 +103,7 @@ static int detect(struct SHT *sht)
*
* NOTE: There is no contention here, because we're already deregistered
* the driver and we're doing each virtual host in turn, not in parallel
* Synchronization: B
LK
, no spinlock.
* Synchronization: B
KL
, no spinlock.
*/
static
int
release
(
struct
Scsi_Host
*
psh
)
{
...
...
drivers/usb/storage/transport.c
View file @
89f0f973
...
...
@@ -562,12 +562,6 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
value
,
index
,
data
,
size
);
US_DEBUGP
(
"usb_stor_control_msg returned %d
\n
"
,
result
);
/* did we abort this command? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"-- transfer aborted
\n
"
);
return
USB_STOR_XFER_ABORTED
;
}
/* a stall indicates a protocol error */
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"-- stall on control pipe
\n
"
);
...
...
@@ -624,12 +618,6 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
return
USB_STOR_XFER_STALLED
;
}
/* did we abort this command? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"-- transfer aborted
\n
"
);
return
USB_STOR_XFER_ABORTED
;
}
/* NAK - that means we've retried a few times already */
if
(
result
==
-
ETIMEDOUT
)
{
US_DEBUGP
(
"-- device NAKed
\n
"
);
...
...
@@ -669,7 +657,7 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
/* initialize the scatter-gather request block */
US_DEBUGP
(
"usb_stor_bulk_transfer_sglist(): xfer %d bytes, "
"%d ent
ir
es
\n
"
,
length
,
num_sg
);
"%d ent
ri
es
\n
"
,
length
,
num_sg
);
result
=
usb_sg_init
(
us
->
current_sg
,
us
->
pusb_dev
,
pipe
,
0
,
sg
,
num_sg
,
length
,
SLAB_NOIO
);
if
(
result
)
{
...
...
@@ -691,26 +679,27 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
}
}
/* wait for the completion of the transfer */
usb_sg_wait
(
us
->
current_sg
);
clear_bit
(
US_FLIDX_CANCEL_SG
,
&
us
->
flags
);
result
=
us
->
current_sg
->
status
;
partial
=
us
->
current_sg
->
bytes
;
US_DEBUGP
(
"usb_sg_wait() returned %d xferre
r
d %d/%d
\n
"
,
US_DEBUGP
(
"usb_sg_wait() returned %d xferred %d/%d
\n
"
,
result
,
partial
,
length
);
if
(
act_len
)
*
act_len
=
partial
;
/* if we stall, we need to clear it before we go on */
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"clearing endpoint halt for pipe 0x%x,"
US_DEBUGP
(
"clearing endpoint halt for pipe 0x%x,
"
"stalled at %d bytes
\n
"
,
pipe
,
partial
);
if
(
usb_stor_clear_halt
(
us
,
pipe
)
<
0
)
return
USB_STOR_XFER_ERROR
;
return
USB_STOR_XFER_STALLED
;
}
/* NAK - that means we've tried this a few times already */
/* NAK - that means we've
re
tried this a few times already */
if
(
result
==
-
ETIMEDOUT
)
{
US_DEBUGP
(
"-- device NAKed
\n
"
);
return
USB_STOR_XFER_ERROR
;
...
...
@@ -738,10 +727,10 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
* Transfer an entire SCSI command's worth of data payload over the bulk
* pipe.
*
* Nore that this uses
the
usb_stor_bulk_transfer_buf() and
* Nore that this uses usb_stor_bulk_transfer_buf() and
* usb_stor_bulk_transfer_sglist() to achieve its goals --
* this function simply determines whether we're going to use
* scatter-gather or not, and acts apropriately.
* scatter-gather or not, and acts ap
p
ropriately.
*/
int
usb_stor_bulk_transfer_sg
(
struct
us_data
*
us
,
unsigned
int
pipe
,
char
*
buf
,
unsigned
int
length_left
,
int
use_sg
,
int
*
residual
)
...
...
@@ -1116,15 +1105,6 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
/* Reset flag for status notification */
clear_bit
(
US_FLIDX_IP_WANTED
,
&
us
->
flags
);
}
/* did we abort this command? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"usb_stor_control_msg(): transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
/* Uh oh... serious problem here */
return
USB_STOR_TRANSPORT_ERROR
;
}
...
...
@@ -1137,12 +1117,6 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
result
=
usb_stor_bulk_transfer_srb
(
us
,
pipe
,
srb
,
transfer_length
);
US_DEBUGP
(
"CBI data stage result is 0x%x
\n
"
,
result
);
/* report any errors */
if
(
result
==
USB_STOR_XFER_ABORTED
)
{
clear_bit
(
US_FLIDX_IP_WANTED
,
&
us
->
flags
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
if
(
result
==
USB_STOR_XFER_ERROR
)
{
clear_bit
(
US_FLIDX_IP_WANTED
,
&
us
->
flags
);
return
USB_STOR_TRANSPORT_ERROR
;
...
...
@@ -1157,7 +1131,7 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
/* has the current command been aborted? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"CBI interrupt aborted
\n
"
);
return
USB_STOR_TRANSPORT_
ABORTED
;
return
USB_STOR_TRANSPORT_
ERROR
;
}
US_DEBUGP
(
"Got interrupt data (0x%x, 0x%x)
\n
"
,
...
...
@@ -1222,13 +1196,6 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us)
/* check the return code for the command */
US_DEBUGP
(
"Call to usb_stor_ctrl_transfer() returned %d
\n
"
,
result
);
/* did we abort this command? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"usb_stor_CB_transport(): transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
if
(
result
!=
USB_STOR_XFER_GOOD
)
{
/* Uh oh... serious problem here */
return
USB_STOR_TRANSPORT_ERROR
;
...
...
@@ -1242,14 +1209,8 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us)
result
=
usb_stor_bulk_transfer_srb
(
us
,
pipe
,
srb
,
transfer_length
);
US_DEBUGP
(
"CB data stage result is 0x%x
\n
"
,
result
);
/* report any errors */
if
(
result
==
USB_STOR_XFER_ABORTED
)
{
return
USB_STOR_TRANSPORT_ABORTED
;
}
if
(
result
==
USB_STOR_XFER_ERROR
)
{
if
(
result
==
USB_STOR_XFER_ERROR
)
return
USB_STOR_TRANSPORT_ERROR
;
}
}
/* STATUS STAGE */
...
...
@@ -1319,12 +1280,6 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
result
=
usb_stor_bulk_transfer_buf
(
us
,
us
->
send_bulk_pipe
,
(
char
*
)
&
bcb
,
US_BULK_CB_WRAP_LEN
,
NULL
);
US_DEBUGP
(
"Bulk command transfer result=%d
\n
"
,
result
);
/* did we abort this command? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"usb_stor_Bulk_transport(): transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
if
(
result
!=
USB_STOR_XFER_GOOD
)
return
USB_STOR_TRANSPORT_ERROR
;
...
...
@@ -1336,10 +1291,6 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
result
=
usb_stor_bulk_transfer_srb
(
us
,
pipe
,
srb
,
transfer_length
);
US_DEBUGP
(
"Bulk data transfer result 0x%x
\n
"
,
result
);
/* if it was aborted, we need to indicate that */
if
(
result
==
USB_STOR_XFER_ABORTED
)
return
USB_STOR_TRANSPORT_ABORTED
;
if
(
result
==
USB_STOR_XFER_ERROR
)
return
USB_STOR_TRANSPORT_ERROR
;
}
...
...
@@ -1353,12 +1304,6 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
result
=
usb_stor_bulk_transfer_buf
(
us
,
us
->
recv_bulk_pipe
,
(
char
*
)
&
bcs
,
US_BULK_CS_WRAP_LEN
,
NULL
);
/* did we abort this command? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"usb_stor_Bulk_transport(): transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
/* did the attempt to read the CSW fail? */
if
(
result
==
USB_STOR_XFER_STALLED
)
{
...
...
@@ -1366,12 +1311,6 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP
(
"Attempting to get CSW (2nd try)...
\n
"
);
result
=
usb_stor_bulk_transfer_buf
(
us
,
us
->
recv_bulk_pipe
,
(
char
*
)
&
bcs
,
US_BULK_CS_WRAP_LEN
,
NULL
);
/* did we abort this command? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"usb_stor_Bulk_transport(): transfer aborted
\n
"
);
return
USB_STOR_TRANSPORT_ABORTED
;
}
}
/* if we still have a failure at this point, we're in trouble */
...
...
drivers/usb/storage/transport.h
View file @
89f0f973
...
...
@@ -121,7 +121,6 @@ struct bulk_cs_wrap {
#define USB_STOR_XFER_SHORT 1
/* transfered less than expected */
#define USB_STOR_XFER_STALLED 2
/* endpoint stalled */
#define USB_STOR_XFER_ERROR 3
/* transfer died in the middle */
#define USB_STOR_XFER_ABORTED 4
/* transfer canceled */
/*
* Transport return codes
...
...
drivers/usb/storage/usb.c
View file @
89f0f973
...
...
@@ -437,41 +437,6 @@ static int usb_stor_control_thread(void * __us)
us
->
srb
->
result
=
GOOD
<<
1
;
}
/* Most USB devices can't handle START_STOP. But we
* need something for media-change, so we'll use TUR
* instead.
*
* We specifically allow this command through if either:
* (a) it's a load/eject command (cmnd[4] & 2)
* (b) it's a multi-target unit (i.e. legacy SCSI adaptor)
*/
else
if
(
us
->
srb
->
cmnd
[
0
]
==
START_STOP
&&
!
(
us
->
srb
->
cmnd
[
4
]
&
2
)
&&
!
(
us
->
flags
&
US_FL_SCM_MULT_TARG
))
{
unsigned
char
saved_cdb
[
16
];
/* largest SCSI-III cmd */
__u8
old_cmd_len
;
US_DEBUGP
(
"Converting START_STOP to TUR
\n
"
);
/* save old command */
memcpy
(
saved_cdb
,
us
->
srb
->
cmnd
,
us
->
srb
->
cmd_len
);
old_cmd_len
=
us
->
srb
->
cmd_len
;
/* set up new command -- preserve LUN */
us
->
srb
->
cmd_len
=
6
;
memset
(
us
->
srb
->
cmnd
,
0
,
us
->
srb
->
cmd_len
);
us
->
srb
->
cmnd
[
0
]
=
TEST_UNIT_READY
;
us
->
srb
->
cmnd
[
1
]
=
saved_cdb
[
1
]
&
0xE0
;
/* do command */
US_DEBUG
(
usb_stor_show_command
(
us
->
srb
));
us
->
proto_handler
(
us
->
srb
,
us
);
/* restore original command */
us
->
srb
->
cmd_len
=
old_cmd_len
;
memcpy
(
us
->
srb
->
cmnd
,
saved_cdb
,
us
->
srb
->
cmd_len
);
}
/* we've got a command, let's do it! */
else
{
US_DEBUG
(
usb_stor_show_command
(
us
->
srb
));
...
...
include/linux/device.h
View file @
89f0f973
...
...
@@ -443,19 +443,19 @@ extern void firmware_uregister(struct subsystem *);
#ifdef DEBUG
#define dev_dbg(dev, format, arg...) \
printk (KERN_DEBUG "%s %s: " format , \
dev.driver->name , dev
.bus_id , ## arg)
(dev).driver->name , (dev)
.bus_id , ## arg)
#else
#define dev_dbg(dev, format, arg...) do {} while (0)
#endif
#define dev_err(dev, format, arg...) \
printk (KERN_ERR "%s %s: " format , \
dev.driver->name , dev
.bus_id , ## arg)
(dev).driver->name , (dev)
.bus_id , ## arg)
#define dev_info(dev, format, arg...) \
printk (KERN_INFO "%s %s: " format , \
dev.driver->name , dev
.bus_id , ## arg)
(dev).driver->name , (dev)
.bus_id , ## arg)
#define dev_warn(dev, format, arg...) \
printk (KERN_WARN "%s %s: " format , \
dev.driver->name , dev
.bus_id , ## arg)
printk (KERN_WARN
ING
"%s %s: " format , \
(dev).driver->name , (dev)
.bus_id , ## arg)
#endif
/* _DEVICE_H_ */
include/linux/kernel.h
View file @
89f0f973
...
...
@@ -105,7 +105,7 @@ extern const char *print_tainted(void);
extern
void
dump_stack
(
void
);
#if DEBUG
#if
def
DEBUG
#define pr_debug(fmt,arg...) \
printk(KERN_DEBUG fmt,##arg)
#else
...
...
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