Commit 340de76c authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linuxusb.bkbits.net/usb-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 491a0f42 e19cd00e
......@@ -20,7 +20,7 @@ devices. Please read joystick.txt before reading further this document.
2. Instructions to the user
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here are instructions on how to compile and use the driver. In fact, this
driver is the normal iforce.o, input.o and evdev.o drivers written by Vojtech
driver is the normal iforce, input and evdev drivers written by Vojtech
Pavlik, plus additions to support force feedback.
Before you start, let me WARN you that some devices shake violently during the
......
......@@ -35,18 +35,18 @@ devices, future use (say 2.5/2.6) is expected to expand to replace
most of the existing input system, which is why it lives in
drivers/input/ instead of drivers/usb/.
The centre of the input drivers is the input.o module, which must be
The centre of the input drivers is the input module, which must be
loaded before any other of the input modules - it serves as a way of
communication between two groups of modules:
1.1 Device drivers
~~~~~~~~~~~~~~~~~~
These modules talk to the hardware (for example via USB), and provide
events (keystrokes, mouse movements) to the input.o module.
events (keystrokes, mouse movements) to the input module.
1.2 Event handlers
~~~~~~~~~~~~~~~~~~
These modules get events from input.o and pass them where needed via
These modules get events from input and pass them where needed via
various interfaces - keystrokes to the kernel, mouse movements via a
simulated PS/2 interface to GPM and X and so on.
......@@ -56,12 +56,12 @@ simulated PS/2 interface to GPM and X and so on.
you'll have to load the following modules (or have them built in to the
kernel):
input.o
mousedev.o
keybdev.o
usbcore.o
usb-uhci.o or usb-ohci.o or uhci.o
hid.o
input
mousedev
keybdev
usbcore
uhci_hcd or ohci_hcd or ehci_hcd
usbhid
After this, the USB keyboard will work straight away, and the USB mouse
will be available as a character device on major 13, minor 63:
......@@ -98,9 +98,9 @@ XFree to this device to use it - GPM should be called like:
however not useful without being handled, so you also will need to use some
of the modules from section 3.2.
3.1.1 hid.o
~~~~~~~~~~~
hid.o is the largest and most complex driver of the whole suite. It
3.1.1 usbhid
~~~~~~~~~~~~
usbhid is the largest and most complex driver of the whole suite. It
handles all HID devices, and because there is a very wide variety of them,
and because the USB HID specification isn't simple, it needs to be this big.
......@@ -115,7 +115,7 @@ interface, but for the UPSs and LCDs it doesn't make much sense. For this,
the hiddev interface was designed. See Documentation/usb/hiddev.txt
for more information about it.
The usage of the hid.o module is very simple, it takes no parameters,
The usage of the usbhid module is very simple, it takes no parameters,
detects everything automatically and when a HID device is inserted, it
detects it appropriately.
......@@ -123,30 +123,30 @@ detects it appropriately.
device that doesn't work well. In that case #define DEBUG at the beginning
of hid-core.c and send me the syslog traces.
3.1.2 usbmouse.o
~~~~~~~~~~~~~~~~
3.1.2 usbmouse
~~~~~~~~~~~~~~
For embedded systems, for mice with broken HID descriptors and just any
other use when the big hid.o wouldn't be a good choice, there is the
usbmouse.c driver. It handles USB mice only. It uses a simpler HIDBP
other use when the big usbhid wouldn't be a good choice, there is the
usbmouse driver. It handles USB mice only. It uses a simpler HIDBP
protocol. This also means the mice must support this simpler protocol. Not
all do. If you don't have any strong reason to use this module, use hid.o
all do. If you don't have any strong reason to use this module, use usbhid
instead.
3.1.3 usbkbd.o
~~~~~~~~~~~~~~
Much like usbmouse.c, this module talks to keyboards with a simplified
3.1.3 usbkbd
~~~~~~~~~~~~
Much like usbmouse, this module talks to keyboards with a simplified
HIDBP protocol. It's smaller, but doesn't support any extra special keys.
Use hid.o instead if there isn't any special reason to use this.
Use usbhid instead if there isn't any special reason to use this.
3.1.4 wacom.o
~~~~~~~~~~~~~
3.1.4 wacom
~~~~~~~~~~~
This is a driver for Wacom Graphire and Intuos tablets. Not for Wacom
PenPartner, that one is handled by the HID driver. Although the Intuos and
Graphire tablets claim that they are HID tablets as well, they are not and
thus need this specific driver.
3.1.5 iforce.o
~~~~~~~~~~~~~~~
3.1.5 iforce
~~~~~~~~~~~~
A driver for I-Force joysticks and wheels, both over USB and RS232.
It includes ForceFeedback support now, even though Immersion
Corp. considers the protocol a trade secret and won't disclose a word
......@@ -157,8 +157,8 @@ about it.
Event handlers distrubite the events from the devices to userland and
kernel, as needed.
3.2.1 keybdev.o
~~~~~~~~~~~~~~~
3.2.1 keybdev
~~~~~~~~~~~~~
keybdev is currently a rather ugly hack that translates the input
events into architecture-specific keyboard raw mode (Xlated AT Set2 on
x86), and passes them into the handle_scancode function of the
......@@ -170,13 +170,13 @@ it.
best if keyboard.c would itself be an event handler. This is done in
the input patch, available on the webpage mentioned below.
3.2.2 mousedev.o
~~~~~~~~~~~~~~~~
3.2.2 mousedev
~~~~~~~~~~~~~~
mousedev is also a hack to make programs that use mouse input
work. It takes events from either mice or digitizers/tablets and makes
a PS/2-style (a la /dev/psaux) mouse device available to the
userland. Ideally, the programs could use a more reasonable interface,
for example evdev.o
for example evdev
Mousedev devices in /dev/input (as shown above) are:
......@@ -207,8 +207,8 @@ program reading the data wishes. You can set GPM and X to any of
these. You'll need ImPS/2 if you want to make use of a wheel on a USB
mouse and ExplorerPS/2 if you want to use extra (up to 5) buttons.
3.2.3 joydev.o
~~~~~~~~~~~~~~
3.2.3 joydev
~~~~~~~~~~~~
Joydev implements v0.x and v1.x Linux joystick api, much like
drivers/char/joystick/joystick.c used to in earlier versions. See
joystick-api.txt in the Documentation subdirectory for details. As
......@@ -223,8 +223,8 @@ on:
And so on up to js31.
3.2.4 evdev.o
~~~~~~~~~~~~~
3.2.4 evdev
~~~~~~~~~~~
evdev is the generic input event interface. It passes the events
generated in the kernel straight to the program, with timestamps. The
API is still evolving, but should be useable now. It's described in
......
......@@ -182,7 +182,7 @@ they're basically souped up CHF sticks.
For other joystick types (more/less axes, hats, and buttons) support
you'll need to specify the types either on the kernel command line or on the
module command line, when inserting analog.o into the kernel. The
module command line, when inserting analog into the kernel. The
parameters are:
analog.map=<type1>,<type2>,<type3>,....
......@@ -503,7 +503,7 @@ and the /dev/input/jsX device should become usable.
3.21 I-Force devices
~~~~~~~~~~~~~~~~~~~~
All I-Force devices are supported by the iforce.o module. This includes:
All I-Force devices are supported by the iforce module. This includes:
* AVB Mag Turbo Force
* AVB Top Shot Pegasus
......
; MS-Windows driver config matching some basic modes of the
; Linux-USB Ethernet/RNDIS gadget firmware:
;
; - RNDIS plus CDC Ethernet ... this may be familiar as a DOCSIS
; cable modem profile, and supports most non-Microsoft USB hosts
;
; - RNDIS plus CDC Subset ... used by hardware that incapable of
; full CDC Ethernet support.
;
; Microsoft only directly supports RNDIS drivers, and bundled them into XP.
; The Microsoft "Remote NDIS USB Driver Kit" is currently found at:
; http://www.microsoft.com/whdc/hwdev/resources/HWservices/rndis.mspx
[Version]
Signature = "$CHICAGO$"
Class = Net
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
Provider = %Linux%
Compatible = 1
MillenniumPreferred = .ME
DriverVer = 03/30/2004,0.0.0.0
; catalog file would be used by WHQL
;CatalogFile = Linux.cat
[Manufacturer]
%Linux% = LinuxDevices,NT.5.1
[LinuxDevices]
; NetChip IDs, used by both firmware modes
%LinuxDevice% = RNDIS, USB\VID_0525&PID_a4a2
[LinuxDevices.NT.5.1]
%LinuxDevice% = RNDIS.NT.5.1, USB\VID_0525&PID_a4a1
[ControlFlags]
ExcludeFromSelect=*
; Windows 98, Windows 98 Second Edition specific sections --------
[RNDIS]
DeviceID = usb8023
MaxInstance = 512
DriverVer = 03/30/2004,0.0.0.0
AddReg = RNDIS_AddReg_98, RNDIS_AddReg_Common
[RNDIS_AddReg_98]
HKR, , DevLoader, 0, *ndis
HKR, , DeviceVxDs, 0, usb8023.sys
HKR, NDIS, LogDriverName, 0, "usb8023"
HKR, NDIS, MajorNdisVersion, 1, 5
HKR, NDIS, MinorNdisVersion, 1, 0
HKR, Ndi\Interfaces, DefUpper, 0, "ndis3,ndis4,ndis5"
HKR, Ndi\Interfaces, DefLower, 0, "ethernet"
HKR, Ndi\Interfaces, UpperRange, 0, "ndis3,ndis4,ndis5"
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
HKR, Ndi\Install, ndis3, 0, "RNDIS_Install_98"
HKR, Ndi\Install, ndis4, 0, "RNDIS_Install_98"
HKR, Ndi\Install, ndis5, 0, "RNDIS_Install_98"
HKR, Ndi, DeviceId, 0, "USB\VID_0525&PID_a4a1"
[RNDIS_Install_98]
CopyFiles=RNDIS_CopyFiles_98
[RNDIS_CopyFiles_98]
usb8023.sys, usb8023w.sys, , 0
rndismp.sys, rndismpw.sys, , 0
; Windows Millennium Edition specific sections --------------------
[RNDIS.ME]
DeviceID = usb8023
MaxInstance = 512
DriverVer = 03/30/2004,0.0.0.0
AddReg = RNDIS_AddReg_ME, RNDIS_AddReg_Common
Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
BusType = 15
[RNDIS_AddReg_ME]
HKR, , DevLoader, 0, *ndis
HKR, , DeviceVxDs, 0, usb8023.sys
HKR, NDIS, LogDriverName, 0, "usb8023"
HKR, NDIS, MajorNdisVersion, 1, 5
HKR, NDIS, MinorNdisVersion, 1, 0
HKR, Ndi\Interfaces, DefUpper, 0, "ndis3,ndis4,ndis5"
HKR, Ndi\Interfaces, DefLower, 0, "ethernet"
HKR, Ndi\Interfaces, UpperRange, 0, "ndis3,ndis4,ndis5"
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
HKR, Ndi\Install, ndis3, 0, "RNDIS_Install_ME"
HKR, Ndi\Install, ndis4, 0, "RNDIS_Install_ME"
HKR, Ndi\Install, ndis5, 0, "RNDIS_Install_ME"
HKR, Ndi, DeviceId, 0, "USB\VID_0525&PID_a4a1"
[RNDIS_Install_ME]
CopyFiles=RNDIS_CopyFiles_ME
[RNDIS_CopyFiles_ME]
usb8023.sys, usb8023m.sys, , 0
rndismp.sys, rndismpm.sys, , 0
; Windows 2000 specific sections ---------------------------------
[RNDIS.NT]
Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
BusType = 15
DriverVer = 03/30/2004,0.0.0.0
AddReg = RNDIS_AddReg_NT, RNDIS_AddReg_Common
CopyFiles = RNDIS_CopyFiles_NT
[RNDIS.NT.Services]
AddService = USB_RNDIS, 2, RNDIS_ServiceInst_NT, RNDIS_EventLog
[RNDIS_CopyFiles_NT]
; no rename of files on Windows 2000, use the 'k' names as is
usb8023k.sys, , , 0
rndismpk.sys, , , 0
[RNDIS_ServiceInst_NT]
DisplayName = %ServiceDisplayName%
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %12%\usb8023k.sys
LoadOrderGroup = NDIS
AddReg = RNDIS_WMI_AddReg_NT
[RNDIS_WMI_AddReg_NT]
HKR, , MofImagePath, 0x00020000, "System32\drivers\rndismpk.sys"
; Windows XP specific sections -----------------------------------
[RNDIS.NT.5.1]
Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
BusType = 15
DriverVer = 03/30/2004,0.0.0.0
AddReg = RNDIS_AddReg_NT, RNDIS_AddReg_Common
; no copyfiles - the files are already in place
[RNDIS.NT.5.1.Services]
AddService = USB_RNDIS, 2, RNDIS_ServiceInst_51, RNDIS_EventLog
[RNDIS_ServiceInst_51]
DisplayName = %ServiceDisplayName%
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %12%\usb8023.sys
LoadOrderGroup = NDIS
AddReg = RNDIS_WMI_AddReg_51
[RNDIS_WMI_AddReg_51]
HKR, , MofImagePath, 0x00020000, "System32\drivers\rndismp.sys"
; Windows 2000 and Windows XP common sections --------------------
[RNDIS_AddReg_NT]
HKR, Ndi, Service, 0, "USB_RNDIS"
HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
[RNDIS_EventLog]
AddReg = RNDIS_EventLog_AddReg
[RNDIS_EventLog_AddReg]
HKR, , EventMessageFile, 0x00020000, "%%SystemRoot%%\System32\netevent.dll"
HKR, , TypesSupported, 0x00010001, 7
; Common Sections -------------------------------------------------
[RNDIS_AddReg_Common]
HKR, NDI\params\NetworkAddress, ParamDesc, 0, %NetworkAddress%
HKR, NDI\params\NetworkAddress, type, 0, "edit"
HKR, NDI\params\NetworkAddress, LimitText, 0, "12"
HKR, NDI\params\NetworkAddress, UpperCase, 0, "1"
HKR, NDI\params\NetworkAddress, default, 0, " "
HKR, NDI\params\NetworkAddress, optional, 0, "1"
[SourceDisksNames]
1=%SourceDisk%,,1
[SourceDisksFiles]
usb8023m.sys=1
rndismpm.sys=1
usb8023w.sys=1
rndismpw.sys=1
usb8023k.sys=1
rndismpk.sys=1
[DestinationDirs]
RNDIS_CopyFiles_98 = 10, system32/drivers
RNDIS_CopyFiles_ME = 10, system32/drivers
RNDIS_CopyFiles_NT = 12
[Strings]
ServiceDisplayName = "USB Remote NDIS Network Device Driver"
NetworkAddress = "Network Address"
Linux = "Linux Developer Community"
LinuxDevice = "Linux USB Ethernet/RNDIS Gadget"
SourceDisk = "Ethernet/RNDIS Gadget Driver Install Disk"
......@@ -848,7 +848,6 @@ CONFIG_USB_MOUSE=m
# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_TEST is not set
......
......@@ -976,7 +976,6 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_GADGET is not set
......
......@@ -1028,7 +1028,6 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
......
......@@ -906,7 +906,6 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_TEST is not set
......
......@@ -986,7 +986,6 @@ CONFIG_USB_TIGL=m
CONFIG_USB_AUERSWALD=m
CONFIG_USB_RIO500=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_BRLVGER=m
CONFIG_USB_LCD=m
# CONFIG_USB_LED is not set
CONFIG_USB_TEST=m
......
......@@ -876,7 +876,6 @@ CONFIG_USB_HPUSBSCSI=m
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
CONFIG_USB_LEGOTOWER=m
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_TEST is not set
......
......@@ -737,7 +737,6 @@ CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
......
......@@ -776,7 +776,6 @@ CONFIG_USB_EZUSB=y
# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_GADGET is not set
......
......@@ -1209,7 +1209,6 @@ CONFIG_USB_EZUSB=y
# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_GADGET is not set
......
......@@ -788,7 +788,6 @@ CONFIG_USB_SERIAL_VISOR=m
# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_GADGET is not set
......
......@@ -1249,7 +1249,6 @@ CONFIG_USB_SERIAL_VISOR=m
# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_GADGET is not set
......
......@@ -775,7 +775,6 @@ CONFIG_USB_SERIAL_VISOR=m
# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_GADGET is not set
......
......@@ -1208,7 +1208,6 @@ CONFIG_USB_EZUSB=y
# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_GADGET is not set
......
......@@ -880,7 +880,6 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_TEST is not set
......
......@@ -880,7 +880,6 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_TEST is not set
......
......@@ -262,7 +262,7 @@ static void ctrl_start_transfer(hfcusb_data * hfc)
hfc->ctrl_urb->transfer_buffer_length = 0;
hfc->ctrl_write.wIndex = hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg;
hfc->ctrl_write.wValue = hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val;
err = usb_submit_urb(hfc->ctrl_urb, GFP_KERNEL); /* start transfer */
err = usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC); /* start transfer */
printk(KERN_DEBUG "ctrl_start_transfer: submit %d\n", err);
}
} /* ctrl_start_transfer */
......@@ -754,7 +754,7 @@ static void tx_iso_complete(struct urb *urb, struct pt_regs *regs)
}
}
errcode = usb_submit_urb(urb, GFP_KERNEL);
errcode = usb_submit_urb(urb, GFP_ATOMIC);
if(errcode < 0)
{
printk(KERN_INFO "HFC-USB: error submitting ISO URB: %i \n", errcode);
......@@ -821,7 +821,7 @@ static void rx_iso_complete(struct urb *urb, struct pt_regs *regs)
fill_isoc_urb(urb, fifo->hfc->dev, fifo->pipe,context_iso_urb->buffer, num_isoc_packets,
fifo->usb_packet_maxlen, fifo->intervall, rx_iso_complete, urb->context);
errcode = usb_submit_urb(urb, GFP_KERNEL);
errcode = usb_submit_urb(urb, GFP_ATOMIC);
if(errcode < 0)
{
printk(KERN_INFO "HFC-USB: error submitting ISO URB: %i \n", errcode);
......@@ -1345,7 +1345,7 @@ char *conf_str[]=
/*************************************************/
/* function called to probe a new plugged device */
/*************************************************/
static int __devinit hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
static int hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev= interface_to_usbdev(intf);
hfcusb_data *context;
......
......@@ -119,7 +119,7 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr)
DBG_ISO_PACKET(0x200,urb);
SUBMIT_URB(urb, GFP_KERNEL);
SUBMIT_URB(urb, GFP_NOIO);
}
/*
......@@ -171,8 +171,8 @@ static void usb_b_out_complete(struct urb *urb, struct pt_regs *regs)
buf_nr = get_buf_nr(b_out->urb, urb);
test_and_clear_bit(buf_nr, &b_out->busy);
if (urb->status < 0) {
if (urb->status != -ENOENT) {
if (unlikely(urb->status < 0)) {
if (urb->status != -ENOENT && urb->status != -ESHUTDOWN) {
WARN("urb status %d",urb->status);
if (b_out->busy == 0) {
st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2 | USB_DIR_OUT, NULL, NULL);
......
......@@ -381,8 +381,8 @@ static void usb_d_out_complete(struct urb *urb, struct pt_regs *regs)
buf_nr = get_buf_nr(d_out->urb, urb);
test_and_clear_bit(buf_nr, &d_out->busy);
if (urb->status < 0) {
if (urb->status != -ENOENT) {
if (unlikely(urb->status < 0)) {
if (urb->status != -ENOENT && urb->status != -ESHUTDOWN) {
WARN("urb status %d",urb->status);
if (d_out->busy == 0) {
st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
......@@ -649,7 +649,7 @@ static void ph_disconnect(struct st5481_adapter *adapter)
st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);
}
static int __devinit st5481_setup_d_out(struct st5481_adapter *adapter)
static int st5481_setup_d_out(struct st5481_adapter *adapter)
{
struct usb_device *dev = adapter->usb_dev;
struct usb_host_interface *altsetting;
......@@ -682,7 +682,7 @@ static void st5481_release_d_out(struct st5481_adapter *adapter)
st5481_release_isocpipes(d_out->urb);
}
int __devinit st5481_setup_d(struct st5481_adapter *adapter)
int st5481_setup_d(struct st5481_adapter *adapter)
{
int retval;
......
......@@ -58,8 +58,8 @@ static LIST_HEAD(adapter_list);
* This function will be called when the adapter is plugged
* into the USB bus.
*/
static int __devinit probe_st5481(struct usb_interface *intf,
const struct usb_device_id *id)
static int probe_st5481(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
struct st5481_adapter *adapter;
......
......@@ -48,7 +48,7 @@ static void usb_next_ctrl_msg(struct urb *urb,
// Prepare the URB
urb->dev = adapter->usb_dev;
SUBMIT_URB(urb, GFP_KERNEL);
SUBMIT_URB(urb, GFP_ATOMIC);
}
/*
......@@ -129,8 +129,8 @@ static void usb_ctrl_complete(struct urb *urb, struct pt_regs *regs)
struct st5481_ctrl *ctrl = &adapter->ctrl;
struct ctrl_msg *ctrl_msg;
if (urb->status < 0) {
if (urb->status != -ENOENT) {
if (unlikely(urb->status < 0)) {
if (urb->status != -ENOENT && urb->status != -ESHUTDOWN) {
WARN("urb status %d",urb->status);
} else {
DBG(1,"urb killed");
......@@ -239,7 +239,7 @@ static void usb_int_complete(struct urb *urb, struct pt_regs *regs)
* initialization
*/
int __devinit st5481_setup_usb(struct st5481_adapter *adapter)
int st5481_setup_usb(struct st5481_adapter *adapter)
{
struct usb_device *dev = adapter->usb_dev;
struct st5481_ctrl *ctrl = &adapter->ctrl;
......@@ -341,7 +341,7 @@ void st5481_release_usb(struct st5481_adapter *adapter)
/*
* Initialize the adapter.
*/
void __devinit st5481_start(struct st5481_adapter *adapter)
void st5481_start(struct st5481_adapter *adapter)
{
static const u8 init_cmd_table[]={
SET_DEFAULT,0,
......@@ -381,7 +381,7 @@ void __devinit st5481_start(struct st5481_adapter *adapter)
/*
* Reset the adapter to default values.
*/
void __devexit st5481_stop(struct st5481_adapter *adapter)
void st5481_stop(struct st5481_adapter *adapter)
{
DBG(8,"");
......@@ -392,7 +392,7 @@ void __devexit st5481_stop(struct st5481_adapter *adapter)
* isochronous USB helpers
*/
static void __devinit
static void
fill_isoc_urb(struct urb *urb, struct usb_device *dev,
unsigned int pipe, void *buf, int num_packets,
int packet_size, usb_complete_t complete,
......@@ -417,7 +417,7 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev,
}
}
int __devinit
int
st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev,
unsigned int pipe, int num_packets,
int packet_size, int buf_size,
......@@ -481,8 +481,8 @@ static void usb_in_complete(struct urb *urb, struct pt_regs *regs)
struct sk_buff *skb;
int len, count, status;
if (urb->status < 0) {
if (urb->status != -ENOENT) {
if (unlikely(urb->status < 0)) {
if (urb->status != -ENOENT && urb->status != -ESHUTDOWN) {
WARN("urb status %d",urb->status);
} else {
DBG(1,"urb killed");
......@@ -529,10 +529,10 @@ static void usb_in_complete(struct urb *urb, struct pt_regs *regs)
urb->dev = in->adapter->usb_dev;
urb->actual_length = 0;
SUBMIT_URB(urb, GFP_KERNEL);
SUBMIT_URB(urb, GFP_ATOMIC);
}
int __devinit st5481_setup_in(struct st5481_in *in)
int st5481_setup_in(struct st5481_in *in)
{
struct usb_device *dev = in->adapter->usb_dev;
int retval;
......
......@@ -1008,7 +1008,7 @@ static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
static int ttusb_setup_interfaces(struct ttusb *ttusb)
{
usb_set_configuration(ttusb->dev, 1);
usb_reset_configuration(ttusb->dev);
usb_set_interface(ttusb->dev, 1, 1);
ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
......@@ -1077,6 +1077,17 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
udev = interface_to_usbdev(intf);
/* Device has already been reset; its configuration was chosen.
* If this fault happens, use a hotplug script to choose the
* right configuration (write bConfigurationValue in sysfs).
*/
if (udev->actconfig->desc.bConfigurationValue != 1) {
dev_err(&intf->dev, "device config is #%d, need #1\n",
udev->actconfig->desc.bConfigurationValue);
return -ENODEV;
}
if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL)))
return -ENOMEM;
......
......@@ -55,8 +55,11 @@ obj-$(CONFIG_USB_MICROTEK) += image/
obj-$(CONFIG_USB_SERIAL) += serial/
obj-$(CONFIG_USB_AUERSWALD) += misc/
obj-$(CONFIG_USB_CYTHERM) += misc/
obj-$(CONFIG_USB_EMI26) += misc/
obj-$(CONFIG_USB_EMI62) += misc/
obj-$(CONFIG_USB_LCD) += misc/
obj-$(CONFIG_USB_LED) += misc/
obj-$(CONFIG_USB_LEGOTOWER) += misc/
obj-$(CONFIG_USB_RIO500) += misc/
obj-$(CONFIG_USB_SPEEDTOUCH) += misc/
......
This diff is collapsed.
......@@ -238,7 +238,7 @@ static char *usb_dump_interface_descriptor(char *start, char *end, const struct
if (start > end)
return start;
lock_kernel(); /* driver might be unloaded */
down_read(&usb_bus_type.subsys.rwsem);
start += sprintf(start, format_iface,
desc->bInterfaceNumber,
desc->bAlternateSetting,
......@@ -247,8 +247,10 @@ static char *usb_dump_interface_descriptor(char *start, char *end, const struct
class_decode(desc->bInterfaceClass),
desc->bInterfaceSubClass,
desc->bInterfaceProtocol,
iface->driver ? iface->driver->name : "(none)");
unlock_kernel();
iface->dev.driver
? iface->dev.driver->name
: "(none)");
up_read(&usb_bus_type.subsys.rwsem);
return start;
}
......
......@@ -124,14 +124,25 @@ static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, l
unsigned int length = le16_to_cpu(config->wTotalLength);
if (*ppos < pos + length) {
/* The descriptor may claim to be longer than it
* really is. Here is the actual allocated length. */
unsigned alloclen =
ps->dev->config[i].desc.wTotalLength;
len = length - (*ppos - pos);
if (len > nbytes)
len = nbytes;
if (copy_to_user(buf,
ps->dev->rawdescriptors[i] + (*ppos - pos), len)) {
ret = -EFAULT;
goto err;
/* Simply don't write (skip over) unallocated parts */
if (alloclen > (*ppos - pos)) {
alloclen -= (*ppos - pos);
if (copy_to_user(buf,
ps->dev->rawdescriptors[i] + (*ppos - pos),
min(len, alloclen))) {
ret = -EFAULT;
goto err;
}
}
*ppos += len;
......@@ -328,18 +339,17 @@ static void driver_disconnect(struct usb_interface *intf)
if (!ps)
return;
/* this waits till synchronous requests complete */
down_write (&ps->devsem);
/* NOTE: this relies on usbcore having canceled and completed
* all pending I/O requests; 2.6 does that.
*/
/* prevent new I/O requests */
ps->dev = 0;
ps->ifclaimed = 0;
clear_bit(intf->cur_altsetting->desc.bInterfaceNumber, &ps->ifclaimed);
usb_set_intfdata (intf, NULL);
/* force async requests to complete */
destroy_all_async (ps);
up_write (&ps->devsem);
}
struct usb_driver usbdevfs_driver = {
......@@ -363,13 +373,15 @@ static int claimintf(struct dev_state *ps, unsigned int intf)
return 0;
iface = dev->actconfig->interface[intf];
err = -EBUSY;
lock_kernel();
/* lock against other changes to driver bindings */
down_write(&usb_bus_type.subsys.rwsem);
if (!usb_interface_claimed(iface)) {
usb_driver_claim_interface(&usbdevfs_driver, iface, ps);
set_bit(intf, &ps->ifclaimed);
err = 0;
}
unlock_kernel();
up_write(&usb_bus_type.subsys.rwsem);
return err;
}
......@@ -384,11 +396,14 @@ static int releaseintf(struct dev_state *ps, unsigned int intf)
err = -EINVAL;
dev = ps->dev;
down(&dev->serialize);
/* lock against other changes to driver bindings */
down_write(&usb_bus_type.subsys.rwsem);
if (test_and_clear_bit(intf, &ps->ifclaimed)) {
iface = dev->actconfig->interface[intf];
usb_driver_release_interface(&usbdevfs_driver, iface);
err = 0;
}
up_write(&usb_bus_type.subsys.rwsem);
up(&dev->serialize);
return err;
}
......@@ -414,6 +429,8 @@ static int findintfep(struct usb_device *dev, unsigned int ep)
if (ep & ~(USB_DIR_IN|0xf))
return -EINVAL;
if (!dev->actconfig)
return -ESRCH;
for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
iface = dev->actconfig->interface[i];
for (j = 0; j < iface->num_altsetting; j++) {
......@@ -434,6 +451,8 @@ static int findintfif(struct usb_device *dev, unsigned int ifn)
if (ifn & ~0xff)
return -EINVAL;
if (!dev->actconfig)
return -ESRCH;
for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
if (dev->actconfig->interface[i]->
altsetting[0].desc.bInterfaceNumber == ifn)
......@@ -684,9 +703,9 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg)
if ((ret = findintfif(ps->dev, gd.interface)) < 0)
return ret;
interface = ps->dev->actconfig->interface[ret];
if (!interface->driver)
if (!interface->dev.driver)
return -ENODATA;
strcpy(gd.driver, interface->driver->name);
strncpy(gd.driver, interface->dev.driver->name, sizeof(gd.driver));
if (copy_to_user(arg, &gd, sizeof(gd)))
return -EFAULT;
return 0;
......@@ -705,26 +724,11 @@ static int proc_connectinfo(struct dev_state *ps, void __user *arg)
static int proc_resetdevice(struct dev_state *ps)
{
int i, ret;
ret = usb_reset_device(ps->dev);
if (ret < 0)
return ret;
for (i = 0; i < ps->dev->actconfig->desc.bNumInterfaces; i++) {
struct usb_interface *intf = ps->dev->actconfig->interface[i];
/* Don't simulate interfaces we've claimed */
if (test_bit(i, &ps->ifclaimed))
continue;
err ("%s - this function is broken", __FUNCTION__);
if (intf->driver && ps->dev) {
usb_probe_interface (&intf->dev);
}
}
/* FIXME when usb_reset_device() is fixed we'll need to grab
* ps->dev->serialize before calling it.
*/
return usb_reset_device(ps->dev);
return 0;
}
static int proc_setintf(struct dev_state *ps, void __user *arg)
......@@ -738,7 +742,7 @@ static int proc_setintf(struct dev_state *ps, void __user *arg)
if ((ret = findintfif(ps->dev, setintf.interface)) < 0)
return ret;
interface = ps->dev->actconfig->interface[ret];
if (interface->driver) {
if (interface->dev.driver) {
if ((ret = checkintf(ps, ret)))
return ret;
}
......@@ -750,10 +754,51 @@ static int proc_setintf(struct dev_state *ps, void __user *arg)
static int proc_setconfig(struct dev_state *ps, void __user *arg)
{
unsigned int u;
int status = 0;
struct usb_host_config *actconfig;
if (get_user(u, (unsigned int __user *)arg))
return -EFAULT;
return usb_set_configuration(ps->dev, u);
down(&ps->dev->serialize);
actconfig = ps->dev->actconfig;
/* Don't touch the device if any interfaces are claimed.
* It could interfere with other drivers' operations, and if
* an interface is claimed by usbfs it could easily deadlock.
*/
if (actconfig) {
int i;
for (i = 0; i < actconfig->desc.bNumInterfaces; ++i) {
if (usb_interface_claimed(actconfig->interface[i])) {
dev_warn (&ps->dev->dev,
"usbfs: interface %d claimed "
"while '%s' sets config #%d\n",
actconfig->interface[i]
->cur_altsetting
->desc.bInterfaceNumber,
current->comm, u);
#if 0 /* FIXME: enable in 2.6.10 or so */
status = -EBUSY;
break;
#endif
}
}
}
/* SET_CONFIGURATION is often abused as a "cheap" driver reset,
* so avoid usb_set_configuration()'s kick to sysfs
*/
if (status == 0) {
if (actconfig && actconfig->desc.bConfigurationValue == u)
status = usb_reset_configuration(ps->dev);
else
status = usb_set_configuration(ps->dev, u);
}
up(&ps->dev->serialize);
return status;
}
static int proc_submiturb(struct dev_state *ps, void __user *arg)
......@@ -1080,58 +1125,51 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg)
}
}
if (!ps->dev)
retval = -ENODEV;
else if (!(ifp = usb_ifnum_to_if (ps->dev, ctrl.ifno)))
if (!ps->dev) {
if (buf)
kfree(buf);
return -ENODEV;
}
down(&ps->dev->serialize);
if (ps->dev->state != USB_STATE_CONFIGURED)
retval = -ENODEV;
else if (!(ifp = usb_ifnum_to_if (ps->dev, ctrl.ifno)))
retval = -EINVAL;
else switch (ctrl.ioctl_code) {
/* disconnect kernel driver from interface, leaving it unbound. */
/* maybe unbound - you get no guarantee it stays unbound */
case USBDEVFS_DISCONNECT:
/* this function is misdesigned - retained for compatibility */
lock_kernel();
driver = ifp->driver;
if (driver) {
dbg ("disconnect '%s' from dev %d interface %d",
driver->name, ps->dev->devnum, ctrl.ifno);
usb_unbind_interface(&ifp->dev);
else switch (ctrl.ioctl_code) {
/* disconnect kernel driver from interface */
case USBDEVFS_DISCONNECT:
down_write(&usb_bus_type.subsys.rwsem);
if (ifp->dev.driver) {
driver = to_usb_driver(ifp->dev.driver);
dev_dbg (&ifp->dev, "disconnect by usbfs\n");
usb_driver_release_interface(driver, ifp);
} else
retval = -ENODATA;
unlock_kernel();
up_write(&usb_bus_type.subsys.rwsem);
break;
/* let kernel drivers try to (re)bind to the interface */
case USBDEVFS_CONNECT:
lock_kernel();
retval = usb_probe_interface (&ifp->dev);
unlock_kernel();
bus_rescan_devices(ifp->dev.bus);
break;
/* talk directly to the interface's driver */
default:
/* BKL used here to protect against changing the binding
* of this driver to this device, as well as unloading its
* driver module.
*/
lock_kernel ();
driver = ifp->driver;
down_read(&usb_bus_type.subsys.rwsem);
if (ifp->dev.driver)
driver = to_usb_driver(ifp->dev.driver);
if (driver == 0 || driver->ioctl == 0) {
unlock_kernel();
retval = -ENOSYS;
retval = -ENOTTY;
} else {
if (!try_module_get (driver->owner)) {
unlock_kernel();
retval = -ENOSYS;
break;
}
unlock_kernel ();
retval = driver->ioctl (ifp, ctrl.ioctl_code, buf);
if (retval == -ENOIOCTLCMD)
retval = -ENOTTY;
module_put (driver->owner);
}
up_read(&usb_bus_type.subsys.rwsem);
}
up(&ps->dev->serialize);
/* cleanup and return */
if (retval >= 0
......
......@@ -55,7 +55,9 @@ set_bConfigurationValue (struct device *dev, const char *buf, size_t count)
if (sscanf (buf, "%u", &config) != 1 || config > 255)
return -EINVAL;
down(&udev->serialize);
value = usb_set_configuration (udev, config);
up(&udev->serialize);
return (value < 0) ? value : count;
}
......@@ -109,6 +111,37 @@ show_speed (struct device *dev, char *buf)
}
static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL);
static ssize_t
show_devnum (struct device *dev, char *buf)
{
struct usb_device *udev;
udev = to_usb_device (dev);
return sprintf (buf, "%d\n", udev->devnum);
}
static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL);
static ssize_t
show_version (struct device *dev, char *buf)
{
struct usb_device *udev;
udev = to_usb_device (dev);
return sprintf (buf, "%2x.%02x\n", udev->descriptor.bcdUSB >> 8,
udev->descriptor.bcdUSB & 0xff);
}
static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
static ssize_t
show_maxchild (struct device *dev, char *buf)
{
struct usb_device *udev;
udev = to_usb_device (dev);
return sprintf (buf, "%d\n", udev->maxchild);
}
static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
/* Descriptor fields */
#define usb_descriptor_attr(field, format_string) \
static ssize_t \
......@@ -159,6 +192,10 @@ void usb_create_driverfs_dev_files (struct usb_device *udev)
device_create_file (dev, &dev_attr_product);
if (udev->descriptor.iSerialNumber)
device_create_file (dev, &dev_attr_serial);
device_create_file (dev, &dev_attr_devnum);
device_create_file (dev, &dev_attr_version);
device_create_file (dev, &dev_attr_maxchild);
}
/* Interface fields */
......
......@@ -80,7 +80,8 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
return -ENODEV;
if (!dev->irq) {
err ("Found HC with no IRQ. Check BIOS/PCI %s setup!",
dev_err (&dev->dev,
"Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
pci_name(dev));
return -ENODEV;
}
......@@ -90,16 +91,17 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
resource = pci_resource_start (dev, 0);
len = pci_resource_len (dev, 0);
if (!request_mem_region (resource, len, driver->description)) {
dbg ("controller already in use");
dev_dbg (&dev->dev, "controller already in use\n");
return -EBUSY;
}
base = ioremap_nocache (resource, len);
if (base == NULL) {
dbg ("error mapping memory");
dev_dbg (&dev->dev, "error mapping memory\n");
retval = -EFAULT;
clean_1:
release_mem_region (resource, len);
err ("init %s fail, %d", pci_name(dev), retval);
dev_err (&dev->dev, "init %s fail, %d\n",
pci_name(dev), retval);
return retval;
}
......@@ -116,7 +118,7 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
break;
}
if (region == PCI_ROM_RESOURCE) {
dbg ("no i/o regions available");
dev_dbg (&dev->dev, "no i/o regions available\n");
return -EBUSY;
}
base = (void *) resource;
......@@ -127,7 +129,7 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
hcd = driver->hcd_alloc ();
if (hcd == NULL){
dbg ("hcd alloc fail");
dev_dbg (&dev->dev, "hcd alloc fail\n");
retval = -ENOMEM;
clean_2:
if (driver->flags & HCD_MEMORY) {
......@@ -135,7 +137,8 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
goto clean_1;
} else {
release_region (resource, len);
err ("init %s fail, %d", pci_name(dev), retval);
dev_err (&dev->dev, "init %s fail, %d\n",
pci_name(dev), retval);
return retval;
}
}
......@@ -193,13 +196,16 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
hcd->self.op = &usb_hcd_operations;
hcd->self.hcpriv = (void *) hcd;
hcd->self.release = &hcd_pci_release;
init_timer (&hcd->rh_timer);
INIT_LIST_HEAD (&hcd->dev_list);
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0)
if ((retval = driver->start (hcd)) < 0) {
dev_err (hcd->self.controller, "init error %d\n", retval);
usb_hcd_pci_remove (dev);
}
return retval;
}
......
......@@ -42,6 +42,8 @@
#include <asm/byteorder.h>
#include <linux/usb.h>
#include "usb.h"
#include "hcd.h"
......@@ -416,9 +418,14 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
default:
/* non-generic request */
urb->status = hcd->driver->hub_control (hcd,
typeReq, wValue, wIndex,
ubuf, wLength);
if (HCD_IS_SUSPENDED (hcd->state))
urb->status = -EAGAIN;
else if (!HCD_IS_RUNNING (hcd->state))
urb->status = -ENODEV;
else
urb->status = hcd->driver->hub_control (hcd,
typeReq, wValue, wIndex,
ubuf, wLength);
break;
error:
/* "protocol stall" on error */
......@@ -678,8 +685,10 @@ int usb_register_bus(struct usb_bus *bus)
if (busnum < USB_MAXBUS) {
set_bit (busnum, busmap.busmap);
bus->busnum = busnum;
} else
warn ("too many buses");
} else {
printk (KERN_ERR "%s: too many buses\n", usbcore_name);
return -E2BIG;
}
snprintf(bus->class_dev.class_id, BUS_ID_SIZE, "usb%d", busnum);
bus->class_dev.class = &usb_host_class;
......@@ -804,7 +813,7 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount)
tmp = HS_USECS_ISO (bytecount);
return tmp;
default:
dbg ("bogus device speed!");
pr_debug ("%s: bogus device speed!\n", usbcore_name);
return -1;
}
}
......
......@@ -275,10 +275,6 @@ extern int usb_set_address(struct usb_device *dev);
#define EndpointOutRequest \
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
/* table 9.6 standard features */
#define DEVICE_REMOTE_WAKEUP 1
#define ENDPOINT_HALT 0
/* class requests from the USB 2.0 hub spec, table 11-15 */
/* GetBusState and SetHubDescriptor are optional, omitted */
#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
......
......@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/completion.h>
#include <linux/sched.h>
#include <linux/list.h>
......@@ -46,6 +47,12 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
static pid_t khubd_pid = 0; /* PID of khubd */
static DECLARE_COMPLETION(khubd_exited);
/* cycle leds on hubs that aren't blinking for attention */
static int blinkenlights = 0;
module_param (blinkenlights, bool, S_IRUGO);
MODULE_PARM_DESC (blinkenlights, "true to cycle leds on hubs");
#ifdef DEBUG
static inline char *portspeed (int portstatus)
{
......@@ -83,7 +90,6 @@ static int clear_hub_feature(struct usb_device *dev, int feature)
/*
* USB 2.0 spec Section 11.24.2.2
* BUG: doesn't handle port indicator selector in high byte of wIndex
*/
static int clear_port_feature(struct usb_device *dev, int port, int feature)
{
......@@ -93,7 +99,6 @@ static int clear_port_feature(struct usb_device *dev, int port, int feature)
/*
* USB 2.0 spec Section 11.24.2.13
* BUG: doesn't handle port indicator selector in high byte of wIndex
*/
static int set_port_feature(struct usb_device *dev, int port, int feature)
{
......@@ -101,6 +106,104 @@ static int set_port_feature(struct usb_device *dev, int port, int feature)
USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
}
/*
* USB 2.0 spec Section 11.24.2.7.1.10 and table 11-7
* for info about using port indicators
*/
static void set_port_led(
struct usb_device *dev,
struct usb_hub *hub,
int port,
int selector
)
{
int status = set_port_feature(dev, (selector << 8) | port,
USB_PORT_FEAT_INDICATOR);
if (status < 0)
dev_dbg (&hub->intf->dev,
"port %d indicator %s status %d\n",
port,
({ char *s; switch (selector) {
case HUB_LED_AMBER: s = "amber"; break;
case HUB_LED_GREEN: s = "green"; break;
case HUB_LED_OFF: s = "off"; break;
case HUB_LED_AUTO: s = "auto"; break;
default: s = "??"; break;
}; s; }),
status);
}
#define LED_CYCLE_PERIOD ((2*HZ)/3)
static void led_work (void *__hub)
{
struct usb_hub *hub = __hub;
struct usb_device *dev = interface_to_usbdev (hub->intf);
unsigned i;
unsigned changed = 0;
int cursor = -1;
if (dev->state != USB_STATE_CONFIGURED)
return;
for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
unsigned selector, mode;
/* 30%-50% duty cycle */
switch (hub->indicator[i]) {
/* cycle marker */
case INDICATOR_CYCLE:
cursor = i;
selector = HUB_LED_AUTO;
mode = INDICATOR_AUTO;
break;
/* blinking green = sw attention */
case INDICATOR_GREEN_BLINK:
selector = HUB_LED_GREEN;
mode = INDICATOR_GREEN_BLINK_OFF;
break;
case INDICATOR_GREEN_BLINK_OFF:
selector = HUB_LED_OFF;
mode = INDICATOR_GREEN_BLINK;
break;
/* blinking amber = hw attention */
case INDICATOR_AMBER_BLINK:
selector = HUB_LED_AMBER;
mode = INDICATOR_AMBER_BLINK_OFF;
break;
case INDICATOR_AMBER_BLINK_OFF:
selector = HUB_LED_OFF;
mode = INDICATOR_AMBER_BLINK;
break;
/* blink green/amber = reserved */
case INDICATOR_ALT_BLINK:
selector = HUB_LED_GREEN;
mode = INDICATOR_ALT_BLINK_OFF;
break;
case INDICATOR_ALT_BLINK_OFF:
selector = HUB_LED_AMBER;
mode = INDICATOR_ALT_BLINK;
break;
default:
continue;
}
if (selector != HUB_LED_AUTO)
changed = 1;
set_port_led(dev, hub, i + 1, selector);
hub->indicator[i] = mode;
}
if (!changed && blinkenlights) {
cursor++;
cursor %= hub->descriptor->bNbrPorts;
set_port_led(dev, hub, cursor + 1, HUB_LED_GREEN);
hub->indicator[cursor] = INDICATOR_CYCLE;
changed++;
}
if (changed)
schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
}
/*
* USB 2.0 spec Section 11.24.2.6
*/
......@@ -212,8 +315,7 @@ static void hub_tt_kevent (void *arg)
spin_lock_irqsave (&hub->tt.lock, flags);
if (status)
err ("usb-%s-%s clear tt %d (%04x) error %d",
dev->bus->bus_name, dev->devpath,
dev_err (&dev->dev, "clear tt %d (%04x) error %d\n",
clear->tt, clear->devinfo, status);
kfree (clear);
}
......@@ -244,8 +346,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe)
* there can be many TTs per hub). even if they're uncommon.
*/
if ((clear = kmalloc (sizeof *clear, SLAB_ATOMIC)) == 0) {
err ("can't save CLEAR_TT_BUFFER state for hub at usb-%s-%s",
dev->bus->bus_name, tt->hub->devpath);
dev_err (&dev->dev, "can't save CLEAR_TT_BUFFER state\n");
/* FIXME recover somehow ... RESET_TT? */
return;
}
......@@ -377,7 +478,7 @@ static int hub_configure(struct usb_hub *hub,
break;
case 0x02:
case 0x03:
dev_dbg(hub_dev, "unknown reserved power switching mode\n");
dev_dbg(hub_dev, "no power switching (usb 1.0)\n");
break;
}
......@@ -436,9 +537,11 @@ static int hub_configure(struct usb_hub *hub,
break;
}
dev_dbg(hub_dev, "Port indicators are %s supported\n",
(hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND)
? "" : "not");
/* probe() zeroes hub->indicator[] */
if (hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND) {
hub->has_indicators = 1;
dev_dbg(hub_dev, "Port indicators are supported\n");
}
dev_dbg(hub_dev, "power on to power good time: %dms\n",
hub->descriptor->bPwrOn2PwrGood * 2);
......@@ -451,12 +554,16 @@ static int hub_configure(struct usb_hub *hub,
goto fail;
}
/* FIXME implement per-port power budgeting;
* enable it for bus-powered hubs.
*/
dev_dbg(hub_dev, "local power source is %s\n",
(hubstatus & HUB_STATUS_LOCAL_POWER)
? "lost (inactive)" : "good");
dev_dbg(hub_dev, "%sover-current condition exists\n",
(hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) == 0)
dev_dbg(hub_dev, "%sover-current condition exists\n",
(hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
/* Start the interrupt endpoint */
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
......@@ -486,6 +593,13 @@ static int hub_configure(struct usb_hub *hub,
/* Wake up khubd */
wake_up(&khubd_wait);
/* maybe start cycling the hub leds */
if (hub->has_indicators && blinkenlights) {
set_port_led(dev, hub, 1, HUB_LED_GREEN);
hub->indicator [0] = INDICATOR_CYCLE;
schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
}
hub_power_on(hub);
return 0;
......@@ -520,7 +634,9 @@ static void hub_disconnect(struct usb_interface *intf)
up(&hub->khubd_sem);
/* assuming we used keventd, it must quiesce too */
if (hub->tt.hub)
if (hub->has_indicators)
cancel_delayed_work (&hub->leds);
if (hub->has_indicators || hub->tt.hub)
flush_scheduled_work ();
if (hub->urb) {
......@@ -596,7 +712,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
hub = kmalloc(sizeof(*hub), GFP_KERNEL);
if (!hub) {
err("couldn't kmalloc hub struct");
dev_dbg (hubdev(dev), "couldn't kmalloc hub struct\n");
return -ENOMEM;
}
......@@ -605,6 +721,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
INIT_LIST_HEAD(&hub->event_list);
hub->intf = intf;
init_MUTEX(&hub->khubd_sem);
INIT_WORK(&hub->leds, led_work, hub);
/* Record the new hub's existence */
spin_lock_irqsave(&hub_event_lock, flags);
......@@ -700,7 +817,7 @@ static void hub_start_disconnect(struct usb_device *dev)
}
}
err("cannot disconnect hub %s", dev->devpath);
dev_err(&dev->dev, "cannot disconnect hub!\n");
}
static int hub_port_status(struct usb_device *dev, int port,
......@@ -1145,7 +1262,7 @@ static int hub_thread(void *__hub)
refrigerator(PF_IOTHREAD);
} while (!signal_pending(current));
dbg("hub_thread exiting");
pr_debug ("%s: khubd exiting\n", usbcore_name);
complete_and_exit(&khubd_exited, 0);
}
......@@ -1176,7 +1293,8 @@ int usb_hub_init(void)
pid_t pid;
if (usb_register(&hub_driver) < 0) {
err("Unable to register USB hub driver");
printk(KERN_ERR "%s: can't register hub driver\n",
usbcore_name);
return -1;
}
......@@ -1189,7 +1307,7 @@ int usb_hub_init(void)
/* Fall through if kernel_thread failed */
usb_deregister(&hub_driver);
err("failed to start hub_thread");
printk(KERN_ERR "%s: can't start khubd\n", usbcore_name);
return -1;
}
......@@ -1300,33 +1418,15 @@ int usb_physical_reset_device(struct usb_device *dev)
kfree(descriptor);
usb_destroy_configuration(dev);
ret = usb_get_device_descriptor(dev, sizeof(dev->descriptor));
if (ret != sizeof(dev->descriptor)) {
if (ret < 0)
err("unable to get device %s descriptor "
"(error=%d)", dev->devpath, ret);
else
err("USB device %s descriptor short read "
"(expected %Zi, got %i)",
dev->devpath,
sizeof(dev->descriptor), ret);
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
return -EIO;
}
/* FIXME Linux doesn't yet handle these "device morphed"
* paths. DFU variants need this to work ... and they
* include the "config descriptors changed" case this
* doesn't yet detect!
*/
dev->state = USB_STATE_NOTATTACHED;
dev_err(&dev->dev, "device morphed (DFU?), nyet supported\n");
ret = usb_get_configuration(dev);
if (ret < 0) {
err("unable to get configuration (error=%d)", ret);
usb_destroy_configuration(dev);
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
}
usb_set_configuration(dev, dev->config[0].desc.bConfigurationValue);
return 1;
return -ENODEV;
}
kfree(descriptor);
......
......@@ -139,6 +139,22 @@ struct usb_hub_descriptor {
__u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
} __attribute__ ((packed));
/* port indicator status selectors, tables 11-7 and 11-25 */
#define HUB_LED_AUTO 0
#define HUB_LED_AMBER 1
#define HUB_LED_GREEN 2
#define HUB_LED_OFF 3
enum hub_led_mode {
INDICATOR_AUTO = 0,
INDICATOR_CYCLE,
/* software blinks for attention: software, hardware, reserved */
INDICATOR_GREEN_BLINK, INDICATOR_GREEN_BLINK_OFF,
INDICATOR_AMBER_BLINK, INDICATOR_AMBER_BLINK_OFF,
INDICATOR_ALT_BLINK, INDICATOR_ALT_BLINK_OFF
} __attribute__ ((packed));
struct usb_device;
/*
......@@ -192,6 +208,10 @@ struct usb_hub {
struct usb_hub_descriptor *descriptor; /* class descriptor */
struct semaphore khubd_sem;
struct usb_tt tt; /* Transaction Translator */
unsigned has_indicators:1;
enum hub_led_mode indicator[USB_MAXCHILDREN];
struct work_struct leds;
};
#endif /* __LINUX_HUB_H */
......@@ -572,13 +572,16 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char
memset(buf,0,size); // Make sure we parse really received data
while (i--) {
/* retries if the returned length was 0; flakey device */
/* retry on length 0 or stall; some devices are flakey */
if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(type << 8) + index, 0, buf, size,
HZ * USB_CTRL_GET_TIMEOUT)) > 0
|| result == -EPIPE)
|| result != -EPIPE)
break;
dev_dbg (&dev->dev, "RETRY descriptor, result %d\n", result);
result = -ENOMSG;
}
return result;
}
......@@ -722,7 +725,8 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
* this request for iso endpoints, which can't halt!
*/
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0,
USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
USB_ENDPOINT_HALT, endp, NULL, 0,
HZ * USB_CTRL_SET_TIMEOUT);
/* don't un-halt or force to DATA0 except on success */
......@@ -928,7 +932,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
iface = usb_ifnum_to_if(dev, interface);
if (!iface) {
warn("selecting invalid interface %d", interface);
dev_dbg(&dev->dev, "selecting invalid interface %d\n",
interface);
return -EINVAL;
}
......@@ -946,8 +951,9 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
* request if the interface only has one alternate setting.
*/
if (ret == -EPIPE && iface->num_altsetting == 1) {
dbg("manual set_interface for dev %d, iface %d, alt %d",
dev->devnum, interface, alternate);
dev_dbg(&dev->dev,
"manual set_interface for iface %d, alt %d\n",
interface, alternate);
manual = 1;
} else if (ret < 0)
return ret;
......@@ -1065,11 +1071,11 @@ int usb_reset_configuration(struct usb_device *dev)
return 0;
}
/**
/*
* usb_set_configuration - Makes a particular device setting be current
* @dev: the device whose configuration is being updated
* @configuration: the configuration being chosen.
* Context: !in_interrupt ()
* Context: !in_interrupt(), caller holds dev->serialize
*
* This is used to enable non-default device modes. Not all devices
* use this kind of configurability; many devices only have one
......@@ -1105,7 +1111,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
struct usb_host_config *cp = NULL;
/* dev->serialize guards all config changes */
down(&dev->serialize);
for (i=0; i<dev->descriptor.bNumConfigurations; i++) {
if (dev->config[i].desc.bConfigurationValue == configuration) {
......@@ -1167,21 +1172,39 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
intf->dev.bus = &usb_bus_type;
intf->dev.dma_mask = dev->dev.dma_mask;
intf->dev.release = release_interface;
device_initialize (&intf->dev);
sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
dev->bus->busnum, dev->devpath,
configuration,
alt->desc.bInterfaceNumber);
}
/* Now that all interfaces are setup, probe() calls
* may claim() any interface that's not yet bound.
* Many class drivers need that: CDC, audio, video, etc.
*/
for (i = 0; i < cp->desc.bNumInterfaces; ++i) {
struct usb_interface *intf = cp->interface[i];
struct usb_interface_descriptor *desc;
desc = &intf->altsetting [0].desc;
dev_dbg (&dev->dev,
"registering %s (config #%d, interface %d)\n",
"adding %s (config #%d, interface %d)\n",
intf->dev.bus_id, configuration,
alt->desc.bInterfaceNumber);
device_register (&intf->dev);
desc->bInterfaceNumber);
ret = device_add (&intf->dev);
if (ret != 0) {
dev_err(&dev->dev,
"device_add(%s) --> %d\n",
intf->dev.bus_id,
ret);
continue;
}
usb_create_driverfs_intf_files (intf);
}
}
out:
up(&dev->serialize);
return ret;
}
......@@ -1224,20 +1247,22 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
/* get langid for strings if it's not yet known */
if (!dev->have_langid) {
err = usb_get_string(dev, 0, 0, tbuf, 4);
err = usb_get_descriptor(dev, USB_DT_STRING, 0, tbuf, 4);
if (err < 0) {
err("error getting string descriptor 0 (error=%d)", err);
dev_err (&dev->dev,
"string descriptor 0 read error: %d\n",
err);
goto errout;
} else if (err < 4 || tbuf[0] < 4) {
err("string descriptor 0 too short");
dev_err (&dev->dev, "string descriptor 0 too short\n");
err = -EINVAL;
goto errout;
} else {
dev->have_langid = -1;
dev->string_langid = tbuf[2] | (tbuf[3]<< 8);
/* always use the first langid listed */
dbg("USB device number %d default language ID 0x%x",
dev->devnum, dev->string_langid);
dev_dbg (&dev->dev, "default language 0x%04x\n",
dev->string_langid);
}
}
......@@ -1246,11 +1271,19 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
*/
err = usb_get_string(dev, dev->string_langid, index, tbuf, 2);
if (err == -EPIPE) {
dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, 2);
err = usb_get_string(dev, dev->string_langid, index, tbuf, 2);
}
if(err<2)
goto errout;
len=tbuf[0];
err = usb_get_string(dev, dev->string_langid, index, tbuf, len);
if (err == -EPIPE) {
dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, len);
err = usb_get_string(dev, dev->string_langid, index, tbuf, len);
}
if (err < 0)
goto errout;
......@@ -1288,6 +1321,5 @@ EXPORT_SYMBOL(usb_string);
// synchronous calls that also maintain usbcore state
EXPORT_SYMBOL(usb_clear_halt);
EXPORT_SYMBOL(usb_reset_configuration);
EXPORT_SYMBOL(usb_set_configuration);
EXPORT_SYMBOL(usb_set_interface);
This diff is collapsed.
......@@ -17,3 +17,7 @@ extern void usb_enable_interface (struct usb_device *dev,
extern int usb_get_device_descriptor(struct usb_device *dev,
unsigned int size);
extern int usb_set_configuration(struct usb_device *dev, int configuration);
/* for labeling diagnostics */
extern const char *usbcore_name;
......@@ -71,8 +71,8 @@ config USB_NET2280
default USB_GADGET
config USB_GADGET_PXA2XX
boolean "PXA 2xx or IXP 42x"
depends on ARCH_PXA || ARCH_IXP425
boolean "PXA 2xx or IXP 4xx"
depends on ARCH_PXA || ARCH_IXP4XX
help
Intel's PXA 2xx series XScale ARM-5TE processors include
an integrated full speed USB 1.1 device controller. The
......@@ -134,6 +134,34 @@ config USB_SA1100
depends on USB_GADGET_SA1100
default USB_GADGET
config USB_GADGET_DUMMY_HCD
boolean "Dummy HCD (DEVELOPMENT)"
depends on USB && EXPERIMENTAL
select USB_GADGET_DUALSPEED
help
This host controller driver emulates USB, looping all data transfer
requests back to a USB "gadget driver" in the same host. The host
side is the master; the gadget side is the slave. Gadget drivers
can be high, full, or low speed; and they have access to endpoints
like those from NET2280, PXA2xx, or SA1100 hardware.
This may help in some stages of creating a driver to embed in a
Linux device, since it lets you debug several parts of the gadget
driver without its hardware or drivers being involved.
Since such a gadget side driver needs to interoperate with a host
side Linux-USB device driver, this may help to debug both sides
of a USB protocol stack.
Say "y" to link the driver statically, or "m" to build a
dynamically linked module called "dummy_hcd" and force all
gadget drivers to also be dynamically linked.
config USB_DUMMY_HCD
tristate
depends on USB_GADGET_DUMMY_HCD
default USB_GADGET
endchoice
config USB_GADGET_DUALSPEED
......@@ -191,9 +219,11 @@ config USB_ETH
favor of simpler vendor-specific hardware, but is widely
supported by firmware for smart network devices.
- On hardware can't implement that protocol, a simpler approach
- On hardware can't implement that protocol, a simple CDC subset
is used, placing fewer demands on USB.
RNDIS support is a third option, more demanding than that subset.
Within the USB device, this gadget driver exposes a network device
"usbX", where X depends on what other networking devices you have.
Treat it like a two-node Ethernet link: host, and gadget.
......@@ -207,6 +237,19 @@ config USB_ETH
Say "y" to link the driver statically, or "m" to build a
dynamically linked module called "g_ether".
config USB_ETH_RNDIS
bool "RNDIS support (EXPERIMENTAL)"
depends on USB_ETH && EXPERIMENTAL
default y
help
Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol,
and Microsoft provides redistributable binary RNDIS drivers for
older versions of Windows.
If you say "y" here, the Ethernet gadget driver will try to provide
a second device configuration, supporting RNDIS to talk to such
Microsoft USB hosts.
config USB_GADGETFS
tristate "Gadget Filesystem (EXPERIMENTAL)"
depends on EXPERIMENTAL
......
#
# USB peripheral controller drivers
#
obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o
obj-$(CONFIG_USB_NET2280) += net2280.o
obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o
obj-$(CONFIG_USB_GOKU) += goku_udc.o
......@@ -8,11 +9,16 @@ obj-$(CONFIG_USB_GOKU) += goku_udc.o
#
# USB gadget drivers
#
g_zero-objs := zero.o usbstring.o config.o
g_ether-objs := ether.o usbstring.o config.o
g_zero-objs := zero.o usbstring.o config.o epautoconf.o
g_ether-objs := ether.o usbstring.o config.o epautoconf.o
g_serial-objs := serial.o usbstring.o
gadgetfs-objs := inode.o usbstring.o
g_file_storage-objs := file_storage.o usbstring.o
gadgetfs-objs := inode.o
g_file_storage-objs := file_storage.o usbstring.o config.o \
epautoconf.o
ifeq ($(CONFIG_USB_ETH_RNDIS),y)
g_ether-objs += rndis.o
endif
obj-$(CONFIG_USB_ZERO) += g_zero.o
obj-$(CONFIG_USB_ETH) += g_ether.o
......
This diff is collapsed.
/*
* epautoconf.c -- endpoint autoconfiguration for usb gadget drivers
*
* Copyright (C) 2004 David Brownell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/usb_ch9.h>
#include <linux/usb_gadget.h>
#include "gadget_chips.h"
/* we must assign addresses for configurable endpoints (like net2280) */
static __initdata unsigned epnum;
// #define MANY_ENDPOINTS
#ifdef MANY_ENDPOINTS
/* more than 15 configurable endpoints */
static __initdata unsigned in_epnum;
#endif
/*
* This should work with endpoints from controller drivers sharing the
* same endpoint naming convention. By example:
*
* - ep1, ep2, ... address is fixed, not direction or type
* - ep1in, ep2out, ... address and direction are fixed, not type
* - ep1-bulk, ep2-bulk, ... address and type are fixed, not direction
* - ep1in-bulk, ep2out-iso, ... all three are fixed
* - ep-* ... no functionality restrictions
*
* Type suffixes are "-bulk", "-iso", or "-int". Numbers are decimal.
* Less common restrictions are implied by gadget_is_*().
*/
static int __init
ep_matches (
struct usb_gadget *gadget,
struct usb_ep *ep,
struct usb_endpoint_descriptor *desc
)
{
u8 type;
const char *tmp;
u16 max;
/* endpoint already claimed? */
if (0 != ep->driver_data)
return 0;
/* only support ep0 for portable CONTROL traffic */
type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
if (USB_ENDPOINT_XFER_CONTROL == type)
return 0;
/* some other naming convention */
if ('e' != ep->name[0])
return 0;
/* type-restriction: "-iso", "-bulk", or "-int".
* direction-restriction: "in", "out".
*/
if ('-' != ep->name[2]) {
tmp = strrchr (ep->name, '-');
if (tmp) {
switch (type) {
case USB_ENDPOINT_XFER_INT:
/* bulk endpoints handle interrupt transfers,
* except the toggle-quirky iso-synch kind
*/
if ('s' == tmp[2]) // == "-iso"
return 0;
/* for now, avoid PXA "interrupt-in";
* it's documented as never using DATA1.
*/
if (gadget_is_pxa (gadget))
return 0;
break;
case USB_ENDPOINT_XFER_BULK:
if ('b' != tmp[1]) // != "-bulk"
return 0;
break;
case USB_ENDPOINT_XFER_ISOC:
if ('s' != tmp[2]) // != "-iso"
return 0;
}
} else {
tmp = ep->name + strlen (ep->name);
}
/* direction-restriction: "..in-..", "out-.." */
tmp--;
if (!isdigit (*tmp)) {
if (desc->bEndpointAddress & USB_DIR_IN) {
if ('n' != *tmp)
return 0;
} else {
if ('t' != *tmp)
return 0;
}
}
}
/* endpoint maxpacket size is an input parameter, except for bulk
* where it's an output parameter representing the full speed limit.
* the usb spec fixes high speed bulk maxpacket at 512 bytes.
*/
max = 0x7ff & le16_to_cpup (&desc->wMaxPacketSize);
switch (type) {
case USB_ENDPOINT_XFER_INT:
/* INT: limit 64 bytes full speed, 1024 high speed */
if (!gadget->is_dualspeed && max > 64)
return 0;
/* FALLTHROUGH */
case USB_ENDPOINT_XFER_ISOC:
/* ISO: limit 1023 bytes full speed, 1024 high speed */
if (ep->maxpacket < max)
return 0;
if (!gadget->is_dualspeed && max > 1023)
return 0;
/* BOTH: "high bandwidth" works only at high speed */
if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) {
if (!gadget->is_dualspeed)
return 0;
/* configure your hardware with enough buffering!! */
}
break;
}
/* MATCH!! */
/* report address */
if (isdigit (ep->name [2])) {
u8 num = simple_strtol (&ep->name [2], NULL, 10);
desc->bEndpointAddress |= num;
#ifdef MANY_ENDPOINTS
} else if (desc->bEndpointAddress & USB_DIR_IN) {
if (++in_epnum > 15)
return 0;
desc->bEndpointAddress = USB_DIR_IN | in_epnum;
#endif
} else {
if (++epnum > 15)
return 0;
desc->bEndpointAddress |= epnum;
}
/* report (variable) full speed bulk maxpacket */
if (USB_ENDPOINT_XFER_BULK == type) {
int size = ep->maxpacket;
/* min() doesn't work on bitfields with gcc-3.5 */
if (size > 64)
size = 64;
desc->wMaxPacketSize = cpu_to_le16(size);
}
return 1;
}
static struct usb_ep * __init
find_ep (struct usb_gadget *gadget, const char *name)
{
struct usb_ep *ep;
list_for_each_entry (ep, &gadget->ep_list, ep_list) {
if (0 == strcmp (ep->name, name))
return ep;
}
return 0;
}
/**
* usb_ep_autoconfig - choose an endpoint matching the descriptor
* @gadget: The device to which the endpoint must belong.
* @desc: Endpoint descriptor, with endpoint direction and transfer mode
* initialized. For periodic transfers, the maximum packet
* size must also be initialized. This is modified on success.
*
* By choosing an endpoint to use with the specified descriptor, this
* routine simplifies writing gadget drivers that work with multiple
* USB device controllers. The endpoint would be passed later to
* usb_ep_enable(), along with some descriptor.
*
* That second descriptor won't always be the same as the first one.
* For example, isochronous endpoints can be autoconfigured for high
* bandwidth, and then used in several lower bandwidth altsettings.
* Also, high and full speed descriptors will be different.
*
* Be sure to examine and test the results of autoconfiguration on your
* hardware. This code may not make the best choices about how to use the
* USB controller, and it can't know all the restrictions that may apply.
* Some combinations of driver and hardware won't be able to autoconfigure.
*
* On success, this returns an un-claimed usb_ep, and modifies the endpoint
* descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value
* is initialized as if the endpoint were used at full speed. To prevent
* the endpoint from being returned by a later autoconfig call, claim it
* by assigning ep->driver_data to some non-null value.
*
* On failure, this returns a null endpoint descriptor.
*/
struct usb_ep * __init usb_ep_autoconfig (
struct usb_gadget *gadget,
struct usb_endpoint_descriptor *desc
)
{
struct usb_ep *ep;
u8 type;
type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
/* First, apply chip-specific "best usage" knowledge.
* This might make a good usb_gadget_ops hook ...
*/
if (gadget_is_net2280 (gadget) && type == USB_ENDPOINT_XFER_INT) {
/* ep-e, ep-f are PIO with only 64 byte fifos */
ep = find_ep (gadget, "ep-e");
if (ep && ep_matches (gadget, ep, desc))
return ep;
ep = find_ep (gadget, "ep-f");
if (ep && ep_matches (gadget, ep, desc))
return ep;
} else if (gadget_is_goku (gadget)) {
if (USB_ENDPOINT_XFER_INT == type) {
/* single buffering is enough */
ep = find_ep (gadget, "ep3-bulk");
if (ep && ep_matches (gadget, ep, desc))
return ep;
} else if (USB_ENDPOINT_XFER_BULK == type
&& (USB_DIR_IN & desc->bEndpointAddress)) {
/* DMA may be available */
ep = find_ep (gadget, "ep2-bulk");
if (ep && ep_matches (gadget, ep, desc))
return ep;
}
} else if (gadget_is_sh (gadget) && USB_ENDPOINT_XFER_INT == type) {
/* single buffering is enough; maybe 8 byte fifo is too */
ep = find_ep (gadget, "ep3in-bulk");
if (ep && ep_matches (gadget, ep, desc))
return ep;
} else if (gadget_is_mq11xx (gadget) && USB_ENDPOINT_XFER_INT == type) {
ep = find_ep (gadget, "ep1-bulk");
if (ep && ep_matches (gadget, ep, desc))
return ep;
}
/* Second, look at endpoints until an unclaimed one looks usable */
list_for_each_entry (ep, &gadget->ep_list, ep_list) {
if (ep_matches (gadget, ep, desc))
return ep;
}
/* Fail */
return 0;
}
/**
* usb_ep_autoconfig_reset - reset endpoint autoconfig state
* @gadget: device for which autoconfig state will be reset
*
* Use this for devices where one configuration may need to assign
* endpoint resources very differently from the next one. It clears
* state such as ep->driver_data and the record of assigned endpoints
* used by usb_ep_autoconfig().
*/
void __init usb_ep_autoconfig_reset (struct usb_gadget *gadget)
{
struct usb_ep *ep;
list_for_each_entry (ep, &gadget->ep_list, ep_list) {
ep->driver_data = 0;
}
#ifdef MANY_ENDPOINTS
in_epnum = 0;
#endif
epnum = 0;
}
This diff is collapsed.
This diff is collapsed.
......@@ -14,6 +14,12 @@
#define gadget_is_net2280(g) 0
#endif
#ifdef CONFIG_USB_GADGET_DUMMY_HCD
#define gadget_is_dummy(g) !strcmp("dummy_udc", (g)->name)
#else
#define gadget_is_dummy(g) 0
#endif
#ifdef CONFIG_USB_GADGET_PXA
#define gadget_is_pxa(g) !strcmp("pxa2xx_udc", (g)->name)
#else
......
......@@ -1562,8 +1562,7 @@ static void ep0_setup(struct goku_udc *dev)
if (dev->ep[tmp].is_in)
goto stall;
}
/* endpoint halt */
if (ctrl.wValue != 0)
if (ctrl.wValue != USB_ENDPOINT_HALT)
goto stall;
if (tmp)
goku_clear_halt(&dev->ep[tmp]);
......
/*
* ndis.h
*
* ntddndis.h modified by Benedikt Spranger <b.spranger@pengutronix.de>
*
* Thanks to the cygwin development team,
* espacially to Casper S. Hornstrup <chorns@users.sourceforge.net>
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef _LINUX_NDIS_H
#define _LINUX_NDIS_H
#define NDIS_STATUS_MULTICAST_FULL 0xC0010009
#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A
#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B
/* NDIS_PNP_CAPABILITIES.Flags constants */
#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001
#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002
#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004
/* Required Object IDs (OIDs) */
#define OID_GEN_SUPPORTED_LIST 0x00010101
#define OID_GEN_HARDWARE_STATUS 0x00010102
#define OID_GEN_MEDIA_SUPPORTED 0x00010103
#define OID_GEN_MEDIA_IN_USE 0x00010104
#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105
#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106
#define OID_GEN_LINK_SPEED 0x00010107
#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108
#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109
#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A
#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B
#define OID_GEN_VENDOR_ID 0x0001010C
#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D
#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E
#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F
#define OID_GEN_DRIVER_VERSION 0x00010110
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111
#define OID_GEN_PROTOCOL_OPTIONS 0x00010112
#define OID_GEN_MAC_OPTIONS 0x00010113
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115
#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116
#define OID_GEN_SUPPORTED_GUIDS 0x00010117
#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118
#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119
#define OID_GEN_MACHINE_NAME 0x0001021A
#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B
#define OID_GEN_VLAN_ID 0x0001021C
/* Optional OIDs */
#define OID_GEN_MEDIA_CAPABILITIES 0x00010201
#define OID_GEN_PHYSICAL_MEDIUM 0x00010202
/* Required statistics OIDs */
#define OID_GEN_XMIT_OK 0x00020101
#define OID_GEN_RCV_OK 0x00020102
#define OID_GEN_XMIT_ERROR 0x00020103
#define OID_GEN_RCV_ERROR 0x00020104
#define OID_GEN_RCV_NO_BUFFER 0x00020105
/* Optional statistics OIDs */
#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201
#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203
#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205
#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207
#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209
#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B
#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
#define OID_GEN_RCV_CRC_ERROR 0x0002020D
#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
#define OID_GEN_GET_TIME_CAPS 0x0002020F
#define OID_GEN_GET_NETCARD_TIME 0x00020210
#define OID_GEN_NETCARD_LOAD 0x00020211
#define OID_GEN_DEVICE_PROFILE 0x00020212
#define OID_GEN_INIT_TIME_MS 0x00020213
#define OID_GEN_RESET_COUNTS 0x00020214
#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215
#define OID_GEN_FRIENDLY_NAME 0x00020216
#define OID_GEN_MINIPORT_INFO 0x00020217
#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218
/* IEEE 802.3 (Ethernet) OIDs */
#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001
#define OID_802_3_PERMANENT_ADDRESS 0x01010101
#define OID_802_3_CURRENT_ADDRESS 0x01010102
#define OID_802_3_MULTICAST_LIST 0x01010103
#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104
#define OID_802_3_MAC_OPTIONS 0x01010105
#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
#define OID_802_3_XMIT_ONE_COLLISION 0x01020102
#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
#define OID_802_3_XMIT_DEFERRED 0x01020201
#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
#define OID_802_3_RCV_OVERRUN 0x01020203
#define OID_802_3_XMIT_UNDERRUN 0x01020204
#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205
#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
/* OID_GEN_MINIPORT_INFO constants */
#define NDIS_MINIPORT_BUS_MASTER 0x00000001
#define NDIS_MINIPORT_WDM_DRIVER 0x00000002
#define NDIS_MINIPORT_SG_LIST 0x00000004
#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008
#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010
#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020
#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040
#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080
#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100
#define NDIS_MINIPORT_IS_NDIS_5 0x00000200
#define NDIS_MINIPORT_IS_CO 0x00000400
#define NDIS_MINIPORT_DESERIALIZE 0x00000800
#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000
#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000
#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000
#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000
#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000
#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000
#define NDIS_MINIPORT_HIDDEN 0x00040000
#define NDIS_MINIPORT_SWENUM 0x00080000
#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000
#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000
#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000
#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000
#define NDIS_MINIPORT_64BITS_DMA 0x01000000
#define NDIS_MEDIUM_802_3 0x00000000
#define NDIS_MEDIUM_802_5 0x00000001
#define NDIS_MEDIUM_FDDI 0x00000002
#define NDIS_MEDIUM_WAN 0x00000003
#define NDIS_MEDIUM_LOCAL_TALK 0x00000004
#define NDIS_MEDIUM_DIX 0x00000005
#define NDIS_MEDIUM_ARCENT_RAW 0x00000006
#define NDIS_MEDIUM_ARCENT_878_2 0x00000007
#define NDIS_MEDIUM_ATM 0x00000008
#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009
#define NDIS_MEDIUM_IRDA 0x0000000A
#define NDIS_MEDIUM_BPC 0x0000000B
#define NDIS_MEDIUM_CO_WAN 0x0000000C
#define NDIS_MEDIUM_1394 0x0000000D
#define NDIS_PACKET_TYPE_DIRECTED 0x00000001
#define NDIS_PACKET_TYPE_MULTICAST 0x00000002
#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
#define NDIS_PACKET_TYPE_BROADCAST 0x00000008
#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
#define NDIS_PACKET_TYPE_SMT 0x00000040
#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
#define NDIS_PACKET_TYPE_GROUP 0x00000100
#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200
#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400
#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800
#define NDIS_MEDIA_STATE_CONNECTED 0x00000000
#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001
#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001
#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002
#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004
#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008
#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010
#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020
#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040
#define NDIS_MAC_OPTION_RESERVED 0x80000000
#endif /* _LINUX_NDIS_H */
......@@ -2401,7 +2401,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
/* hw handles device features */
if (u.r.bRequestType != USB_RECIP_ENDPOINT)
goto delegate;
if (u.r.wValue != 0 /* HALT feature */
if (u.r.wValue != USB_ENDPOINT_HALT
|| u.r.wLength != 0)
goto do_stall;
if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
......@@ -2418,7 +2418,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
/* hw handles device features */
if (u.r.bRequestType != USB_RECIP_ENDPOINT)
goto delegate;
if (u.r.wValue != 0 /* HALT feature */
if (u.r.wValue != USB_ENDPOINT_HALT
|| u.r.wLength != 0)
goto do_stall;
if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -12,6 +12,7 @@
#include <linux/list.h>
#include <linux/string.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/usb_ch9.h>
#include <linux/usb_gadget.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment