Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (94 commits) USB: remove err() macro from more usb drivers USB: remove err() macro from usb misc drivers USB: remove err() macro from usb core code USB: remove err() macro from usb class drivers USB: remove use of err() in drivers/usb/serial USB: remove info() macro from usb mtd drivers USB: remove info() macro from usb input drivers USB: remove info() macro from usb network drivers USB: remove info() macro from remaining usb drivers USB: remove info() macro from usb/misc drivers USB: remove info() macro from usb/serial drivers USB: remove warn macro from HID core USB: remove warn() macro from usb drivers USB: remove warn() macro from usb net drivers USB: remove warn() macro from usb media drivers USB: remove warn() macro from usb input drivers usb/fsl_qe_udc: clear data toggle on clear halt request usb/fsl_qe_udc: fix response to get status request fsl_usb2_udc: Fix oops on probe failure. fsl_usb2_udc: Add a wmb before priming endpoint. ...
This commit is contained in:
Коммит
0cfd81031a
|
@ -0,0 +1,62 @@
|
|||
What: /sys/bus/usb/drivers/usbtmc/devices/*/interface_capabilities
|
||||
What: /sys/bus/usb/drivers/usbtmc/devices/*/device_capabilities
|
||||
Date: August 2008
|
||||
Contact: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
Description:
|
||||
These files show the various USB TMC capabilities as described
|
||||
by the device itself. The full description of the bitfields
|
||||
can be found in the USB TMC documents from the USB-IF entitled
|
||||
"Universal Serial Bus Test and Measurement Class Specification
|
||||
(USBTMC) Revision 1.0" section 4.2.1.8.
|
||||
|
||||
The files are read only.
|
||||
|
||||
|
||||
What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_interface_capabilities
|
||||
What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_device_capabilities
|
||||
Date: August 2008
|
||||
Contact: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
Description:
|
||||
These files show the various USB TMC capabilities as described
|
||||
by the device itself. The full description of the bitfields
|
||||
can be found in the USB TMC documents from the USB-IF entitled
|
||||
"Universal Serial Bus Test and Measurement Class, Subclass
|
||||
USB488 Specification (USBTMC-USB488) Revision 1.0" section
|
||||
4.2.2.
|
||||
|
||||
The files are read only.
|
||||
|
||||
|
||||
What: /sys/bus/usb/drivers/usbtmc/devices/*/TermChar
|
||||
Date: August 2008
|
||||
Contact: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
Description:
|
||||
This file is the TermChar value to be sent to the USB TMC
|
||||
device as described by the document, "Universal Serial Bus Test
|
||||
and Measurement Class Specification
|
||||
(USBTMC) Revision 1.0" as published by the USB-IF.
|
||||
|
||||
Note that the TermCharEnabled file determines if this value is
|
||||
sent to the device or not.
|
||||
|
||||
|
||||
What: /sys/bus/usb/drivers/usbtmc/devices/*/TermCharEnabled
|
||||
Date: August 2008
|
||||
Contact: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
Description:
|
||||
This file determines if the TermChar is to be sent to the
|
||||
device on every transaction or not. For more details about
|
||||
this, please see the document, "Universal Serial Bus Test and
|
||||
Measurement Class Specification (USBTMC) Revision 1.0" as
|
||||
published by the USB-IF.
|
||||
|
||||
|
||||
What: /sys/bus/usb/drivers/usbtmc/devices/*/auto_abort
|
||||
Date: August 2008
|
||||
Contact: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
Description:
|
||||
This file determines if the the transaction of the USB TMC
|
||||
device is to be automatically aborted if there is any error.
|
||||
For more details about this, please see the document,
|
||||
"Universal Serial Bus Test and Measurement Class Specification
|
||||
(USBTMC) Revision 1.0" as published by the USB-IF.
|
|
@ -85,3 +85,19 @@ Description:
|
|||
Users:
|
||||
PowerTOP <power@bughost.org>
|
||||
http://www.lesswatts.org/projects/powertop/
|
||||
|
||||
What: /sys/bus/usb/device/<busnum>-<devnum>...:<config num>-<interface num>/supports_autosuspend
|
||||
Date: January 2008
|
||||
KernelVersion: 2.6.27
|
||||
Contact: Sarah Sharp <sarah.a.sharp@intel.com>
|
||||
Description:
|
||||
When read, this file returns 1 if the interface driver
|
||||
for this interface supports autosuspend. It also
|
||||
returns 1 if no driver has claimed this interface, as an
|
||||
unclaimed interface will not stop the device from being
|
||||
autosuspended if all other interface drivers are idle.
|
||||
The file returns 0 if autosuspend support has not been
|
||||
added to the driver.
|
||||
Users:
|
||||
USB PM tool
|
||||
git://git.moblin.org/users/sarah/usb-pm-tool/
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
Where: /sys/bus/usb/.../powered
|
||||
Date: August 2008
|
||||
Kernel Version: 2.6.26
|
||||
Contact: Harrison Metzger <harrisonmetz@gmail.com>
|
||||
Description: Controls whether the device's display will powered.
|
||||
A value of 0 is off and a non-zero value is on.
|
||||
|
||||
Where: /sys/bus/usb/.../mode_msb
|
||||
Where: /sys/bus/usb/.../mode_lsb
|
||||
Date: August 2008
|
||||
Kernel Version: 2.6.26
|
||||
Contact: Harrison Metzger <harrisonmetz@gmail.com>
|
||||
Description: Controls the devices display mode.
|
||||
For a 6 character display the values are
|
||||
MSB 0x06; LSB 0x3F, and
|
||||
for an 8 character display the values are
|
||||
MSB 0x08; LSB 0xFF.
|
||||
|
||||
Where: /sys/bus/usb/.../textmode
|
||||
Date: August 2008
|
||||
Kernel Version: 2.6.26
|
||||
Contact: Harrison Metzger <harrisonmetz@gmail.com>
|
||||
Description: Controls the way the device interprets its text buffer.
|
||||
raw: each character controls its segment manually
|
||||
hex: each character is between 0-15
|
||||
ascii: each character is between '0'-'9' and 'A'-'F'.
|
||||
|
||||
Where: /sys/bus/usb/.../text
|
||||
Date: August 2008
|
||||
Kernel Version: 2.6.26
|
||||
Contact: Harrison Metzger <harrisonmetz@gmail.com>
|
||||
Description: The text (or data) for the device to display
|
||||
|
||||
Where: /sys/bus/usb/.../decimals
|
||||
Date: August 2008
|
||||
Kernel Version: 2.6.26
|
||||
Contact: Harrison Metzger <harrisonmetz@gmail.com>
|
||||
Description: Controls the decimal places on the device.
|
||||
To set the nth decimal place, give this field
|
||||
the value of 10 ** n. Assume this field has
|
||||
the value k and has 1 or more decimal places set,
|
||||
to set the mth place (where m is not already set),
|
||||
change this fields value to k + 10 ** m.
|
|
@ -557,6 +557,9 @@ Near-term plans include converting all of them, except for "gadgetfs".
|
|||
</para>
|
||||
|
||||
!Edrivers/usb/gadget/f_acm.c
|
||||
!Edrivers/usb/gadget/f_ecm.c
|
||||
!Edrivers/usb/gadget/f_subset.c
|
||||
!Edrivers/usb/gadget/f_obex.c
|
||||
!Edrivers/usb/gadget/f_serial.c
|
||||
|
||||
</sect1>
|
||||
|
|
|
@ -2571,6 +2571,9 @@ Your cooperation is appreciated.
|
|||
160 = /dev/usb/legousbtower0 1st USB Legotower device
|
||||
...
|
||||
175 = /dev/usb/legousbtower15 16th USB Legotower device
|
||||
176 = /dev/usb/usbtmc1 First USB TMC device
|
||||
...
|
||||
192 = /dev/usb/usbtmc16 16th USB TMC device
|
||||
240 = /dev/usb/dabusb0 First daubusb device
|
||||
...
|
||||
243 = /dev/usb/dabusb3 Fourth dabusb device
|
||||
|
|
|
@ -92,6 +92,7 @@ Code Seq# Include File Comments
|
|||
'J' 00-1F drivers/scsi/gdth_ioctl.h
|
||||
'K' all linux/kd.h
|
||||
'L' 00-1F linux/loop.h
|
||||
'L' 20-2F driver/usb/misc/vstusb.h
|
||||
'L' E0-FF linux/ppdd.h encrypted disk device driver
|
||||
<http://linux01.gwdg.de/~alatham/ppdd.html>
|
||||
'M' all linux/soundcard.h
|
||||
|
@ -110,6 +111,8 @@ Code Seq# Include File Comments
|
|||
'W' 00-1F linux/wanrouter.h conflict!
|
||||
'X' all linux/xfs_fs.h
|
||||
'Y' all linux/cyclades.h
|
||||
'[' 00-07 linux/usb/usbtmc.h USB Test and Measurement Devices
|
||||
<mailto:gregkh@suse.de>
|
||||
'a' all ATM on linux
|
||||
<http://lrcwww.epfl.ch/linux-atm/magic.html>
|
||||
'b' 00-FF bit3 vme host bridge
|
||||
|
|
|
@ -2253,6 +2253,25 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
autosuspended. Devices for which the delay is set
|
||||
to a negative value won't be autosuspended at all.
|
||||
|
||||
usbcore.usbfs_snoop=
|
||||
[USB] Set to log all usbfs traffic (default 0 = off).
|
||||
|
||||
usbcore.blinkenlights=
|
||||
[USB] Set to cycle leds on hubs (default 0 = off).
|
||||
|
||||
usbcore.old_scheme_first=
|
||||
[USB] Start with the old device initialization
|
||||
scheme (default 0 = off).
|
||||
|
||||
usbcore.use_both_schemes=
|
||||
[USB] Try the other device initialization scheme
|
||||
if the first one fails (default 1 = enabled).
|
||||
|
||||
usbcore.initial_descriptor_timeout=
|
||||
[USB] Specifies timeout for the initial 64-byte
|
||||
USB_REQ_GET_DESCRIPTOR request in milliseconds
|
||||
(default 5000 = 5.0 seconds).
|
||||
|
||||
usbhid.mousepoll=
|
||||
[USBHID] The interval which mice are to be polled at.
|
||||
|
||||
|
|
|
@ -52,6 +52,11 @@ Therefore no guarantee is made that the URBs have been unlinked when
|
|||
the call returns. They may be unlinked later but will be unlinked in
|
||||
finite time.
|
||||
|
||||
usb_scuttle_anchored_urbs()
|
||||
---------------------------
|
||||
|
||||
All URBs of an anchor are unanchored en masse.
|
||||
|
||||
usb_wait_anchor_empty_timeout()
|
||||
-------------------------------
|
||||
|
||||
|
@ -59,4 +64,16 @@ This function waits for all URBs associated with an anchor to finish
|
|||
or a timeout, whichever comes first. Its return value will tell you
|
||||
whether the timeout was reached.
|
||||
|
||||
usb_anchor_empty()
|
||||
------------------
|
||||
|
||||
Returns true if no URBs are associated with an anchor. Locking
|
||||
is the caller's responsibility.
|
||||
|
||||
usb_get_from_anchor()
|
||||
---------------------
|
||||
|
||||
Returns the oldest anchored URB of an anchor. The URB is unanchored
|
||||
and returned with a reference. As you may mix URBs to several
|
||||
destinations in one anchor you have no guarantee the chronologically
|
||||
first submitted URB is returned.
|
|
@ -0,0 +1,46 @@
|
|||
USB 7-Segment Numeric Display
|
||||
Manufactured by Delcom Engineering
|
||||
|
||||
Device Information
|
||||
------------------
|
||||
USB VENDOR_ID 0x0fc5
|
||||
USB PRODUCT_ID 0x1227
|
||||
Both the 6 character and 8 character displays have PRODUCT_ID,
|
||||
and according to Delcom Engineering no queryable information
|
||||
can be obtained from the device to tell them apart.
|
||||
|
||||
Device Modes
|
||||
------------
|
||||
By default, the driver assumes the display is only 6 characters
|
||||
The mode for 6 characters is:
|
||||
MSB 0x06; LSB 0x3f
|
||||
For the 8 character display:
|
||||
MSB 0x08; LSB 0xff
|
||||
The device can accept "text" either in raw, hex, or ascii textmode.
|
||||
raw controls each segment manually,
|
||||
hex expects a value between 0-15 per character,
|
||||
ascii expects a value between '0'-'9' and 'A'-'F'.
|
||||
The default is ascii.
|
||||
|
||||
Device Operation
|
||||
----------------
|
||||
1. Turn on the device:
|
||||
echo 1 > /sys/bus/usb/.../powered
|
||||
2. Set the device's mode:
|
||||
echo $mode_msb > /sys/bus/usb/.../mode_msb
|
||||
echo $mode_lsb > /sys/bus/usb/.../mode_lsb
|
||||
3. Set the textmode:
|
||||
echo $textmode > /sys/bus/usb/.../textmode
|
||||
4. set the text (for example):
|
||||
echo "123ABC" > /sys/bus/usb/.../text (ascii)
|
||||
echo "A1B2" > /sys/bus/usb/.../text (ascii)
|
||||
echo -ne "\x01\x02\x03" > /sys/bus/usb/.../text (hex)
|
||||
5. Set the decimal places.
|
||||
The device has either 6 or 8 decimal points.
|
||||
to set the nth decimal place calculate 10 ** n
|
||||
and echo it in to /sys/bus/usb/.../decimals
|
||||
To set multiple decimals points sum up each power.
|
||||
For example, to set the 0th and 3rd decimal place
|
||||
echo 1001 > /sys/bus/usb/.../decimals
|
||||
|
||||
|
|
@ -350,12 +350,12 @@ without holding the mutex.
|
|||
|
||||
There also are a couple of utility routines drivers can use:
|
||||
|
||||
usb_autopm_enable() sets pm_usage_cnt to 1 and then calls
|
||||
usb_autopm_set_interface(), which will attempt an autoresume.
|
||||
|
||||
usb_autopm_disable() sets pm_usage_cnt to 0 and then calls
|
||||
usb_autopm_enable() sets pm_usage_cnt to 0 and then calls
|
||||
usb_autopm_set_interface(), which will attempt an autosuspend.
|
||||
|
||||
usb_autopm_disable() sets pm_usage_cnt to 1 and then calls
|
||||
usb_autopm_set_interface(), which will attempt an autoresume.
|
||||
|
||||
The conventional usage pattern is that a driver calls
|
||||
usb_autopm_get_interface() in its open routine and
|
||||
usb_autopm_put_interface() in its close or release routine. But
|
||||
|
|
|
@ -349,8 +349,6 @@ struct ub_dev {
|
|||
|
||||
struct work_struct reset_work;
|
||||
wait_queue_head_t reset_wait;
|
||||
|
||||
int sg_stat[6];
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -685,7 +683,6 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
|
|||
goto drop;
|
||||
}
|
||||
urq->nsg = n_elem;
|
||||
sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
|
||||
|
||||
if (blk_pc_request(rq)) {
|
||||
ub_cmd_build_packet(sc, lun, cmd, urq);
|
||||
|
|
|
@ -428,7 +428,7 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
|
|||
usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
|
||||
if (!usbhid->out[usbhid->outhead].raw_report) {
|
||||
spin_unlock_irqrestore(&usbhid->outlock, flags);
|
||||
warn("output queueing failed");
|
||||
dev_warn(&hid->dev, "output queueing failed\n");
|
||||
return;
|
||||
}
|
||||
hid_output_report(report, usbhid->out[usbhid->outhead].raw_report);
|
||||
|
@ -455,7 +455,7 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
|
|||
usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
|
||||
if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
|
||||
spin_unlock_irqrestore(&usbhid->ctrllock, flags);
|
||||
warn("control queueing failed");
|
||||
dev_warn(&hid->dev, "control queueing failed\n");
|
||||
return;
|
||||
}
|
||||
hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report);
|
||||
|
|
|
@ -197,13 +197,16 @@ static unsigned char find_button(struct iforce *iforce, signed short button)
|
|||
* Analyse the changes in an effect, and tell if we need to send an condition
|
||||
* parameter packet
|
||||
*/
|
||||
static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new)
|
||||
static int need_condition_modifier(struct iforce *iforce,
|
||||
struct ff_effect *old,
|
||||
struct ff_effect *new)
|
||||
{
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
if (new->type != FF_SPRING && new->type != FF_FRICTION) {
|
||||
warn("bad effect type in need_condition_modifier");
|
||||
dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -222,10 +225,13 @@ static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new)
|
|||
* Analyse the changes in an effect, and tell if we need to send a magnitude
|
||||
* parameter packet
|
||||
*/
|
||||
static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect)
|
||||
static int need_magnitude_modifier(struct iforce *iforce,
|
||||
struct ff_effect *old,
|
||||
struct ff_effect *effect)
|
||||
{
|
||||
if (effect->type != FF_CONSTANT) {
|
||||
warn("bad effect type in need_envelope_modifier");
|
||||
dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -236,7 +242,8 @@ static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effe
|
|||
* Analyse the changes in an effect, and tell if we need to send an envelope
|
||||
* parameter packet
|
||||
*/
|
||||
static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effect)
|
||||
static int need_envelope_modifier(struct iforce *iforce, struct ff_effect *old,
|
||||
struct ff_effect *effect)
|
||||
{
|
||||
switch (effect->type) {
|
||||
case FF_CONSTANT:
|
||||
|
@ -256,7 +263,8 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec
|
|||
break;
|
||||
|
||||
default:
|
||||
warn("bad effect type in need_envelope_modifier");
|
||||
dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -266,10 +274,12 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec
|
|||
* Analyse the changes in an effect, and tell if we need to send a periodic
|
||||
* parameter effect
|
||||
*/
|
||||
static int need_period_modifier(struct ff_effect *old, struct ff_effect *new)
|
||||
static int need_period_modifier(struct iforce *iforce, struct ff_effect *old,
|
||||
struct ff_effect *new)
|
||||
{
|
||||
if (new->type != FF_PERIODIC) {
|
||||
warn("bad effect type in need_period_modifier");
|
||||
dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
return (old->u.periodic.period != new->u.periodic.period
|
||||
|
@ -355,7 +365,7 @@ int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, stru
|
|||
int param2_err = 1;
|
||||
int core_err = 0;
|
||||
|
||||
if (!old || need_period_modifier(old, effect)) {
|
||||
if (!old || need_period_modifier(iforce, old, effect)) {
|
||||
param1_err = make_period_modifier(iforce, mod1_chunk,
|
||||
old != NULL,
|
||||
effect->u.periodic.magnitude, effect->u.periodic.offset,
|
||||
|
@ -365,7 +375,7 @@ int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, stru
|
|||
set_bit(FF_MOD1_IS_USED, core_effect->flags);
|
||||
}
|
||||
|
||||
if (!old || need_envelope_modifier(old, effect)) {
|
||||
if (!old || need_envelope_modifier(iforce, old, effect)) {
|
||||
param2_err = make_envelope_modifier(iforce, mod2_chunk,
|
||||
old !=NULL,
|
||||
effect->u.periodic.envelope.attack_length,
|
||||
|
@ -425,7 +435,7 @@ int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, stru
|
|||
int param2_err = 1;
|
||||
int core_err = 0;
|
||||
|
||||
if (!old || need_magnitude_modifier(old, effect)) {
|
||||
if (!old || need_magnitude_modifier(iforce, old, effect)) {
|
||||
param1_err = make_magnitude_modifier(iforce, mod1_chunk,
|
||||
old != NULL,
|
||||
effect->u.constant.level);
|
||||
|
@ -434,7 +444,7 @@ int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, stru
|
|||
set_bit(FF_MOD1_IS_USED, core_effect->flags);
|
||||
}
|
||||
|
||||
if (!old || need_envelope_modifier(old, effect)) {
|
||||
if (!old || need_envelope_modifier(iforce, old, effect)) {
|
||||
param2_err = make_envelope_modifier(iforce, mod2_chunk,
|
||||
old != NULL,
|
||||
effect->u.constant.envelope.attack_length,
|
||||
|
@ -487,7 +497,7 @@ int iforce_upload_condition(struct iforce *iforce, struct ff_effect *effect, str
|
|||
default: return -1;
|
||||
}
|
||||
|
||||
if (!old || need_condition_modifier(old, effect)) {
|
||||
if (!old || need_condition_modifier(iforce, old, effect)) {
|
||||
param_err = make_condition_modifier(iforce, mod1_chunk,
|
||||
old != NULL,
|
||||
effect->u.condition[0].right_saturation,
|
||||
|
|
|
@ -218,7 +218,9 @@ static void iforce_release(struct input_dev *dev)
|
|||
/* Check: no effects should be present in memory */
|
||||
for (i = 0; i < dev->ff->max_effects; i++) {
|
||||
if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) {
|
||||
warn("iforce_release: Device still owns effects");
|
||||
dev_warn(&dev->dev,
|
||||
"%s: Device still owns effects\n",
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -335,26 +337,26 @@ int iforce_init_device(struct iforce *iforce)
|
|||
if (!iforce_get_id_packet(iforce, "M"))
|
||||
input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
|
||||
else
|
||||
warn("Device does not respond to id packet M");
|
||||
dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n");
|
||||
|
||||
if (!iforce_get_id_packet(iforce, "P"))
|
||||
input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1];
|
||||
else
|
||||
warn("Device does not respond to id packet P");
|
||||
dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n");
|
||||
|
||||
if (!iforce_get_id_packet(iforce, "B"))
|
||||
iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1];
|
||||
else
|
||||
warn("Device does not respond to id packet B");
|
||||
dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n");
|
||||
|
||||
if (!iforce_get_id_packet(iforce, "N"))
|
||||
ff_effects = iforce->edata[1];
|
||||
else
|
||||
warn("Device does not respond to id packet N");
|
||||
dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n");
|
||||
|
||||
/* Check if the device can store more effects than the driver can really handle */
|
||||
if (ff_effects > IFORCE_EFFECTS_MAX) {
|
||||
warn("Limiting number of effects to %d (device reports %d)",
|
||||
dev_warn(&iforce->dev->dev, "Limiting number of effects to %d (device reports %d)\n",
|
||||
IFORCE_EFFECTS_MAX, ff_effects);
|
||||
ff_effects = IFORCE_EFFECTS_MAX;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,8 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
|
|||
|
||||
|
||||
if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) {
|
||||
warn("not enough space in xmit buffer to send new packet");
|
||||
dev_warn(&iforce->dev->dev,
|
||||
"not enough space in xmit buffer to send new packet\n");
|
||||
spin_unlock_irqrestore(&iforce->xmit_lock, flags);
|
||||
return -1;
|
||||
}
|
||||
|
@ -148,7 +149,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
warn("unused effect %04x updated !!!", addr);
|
||||
dev_warn(&iforce->dev->dev, "unused effect %04x updated !!!\n", addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -159,7 +160,8 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
|
|||
static int being_used = 0;
|
||||
|
||||
if (being_used)
|
||||
warn("re-entrant call to iforce_process %d", being_used);
|
||||
dev_warn(&iforce->dev->dev,
|
||||
"re-entrant call to iforce_process %d\n", being_used);
|
||||
being_used++;
|
||||
|
||||
#ifdef CONFIG_JOYSTICK_IFORCE_232
|
||||
|
|
|
@ -64,7 +64,7 @@ void iforce_usb_xmit(struct iforce *iforce)
|
|||
|
||||
if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) {
|
||||
clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
|
||||
warn("usb_submit_urb failed %d\n", n);
|
||||
dev_warn(&iforce->dev->dev, "usb_submit_urb failed %d\n", n);
|
||||
}
|
||||
|
||||
/* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended.
|
||||
|
|
|
@ -911,7 +911,7 @@ static int __init usb_xpad_init(void)
|
|||
{
|
||||
int result = usb_register(&xpad_driver);
|
||||
if (result == 0)
|
||||
info(DRIVER_DESC);
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -285,7 +285,6 @@ static const struct {
|
|||
};
|
||||
|
||||
/* Local function prototypes */
|
||||
static void ati_remote_dump (unsigned char *data, unsigned int actual_length);
|
||||
static int ati_remote_open (struct input_dev *inputdev);
|
||||
static void ati_remote_close (struct input_dev *inputdev);
|
||||
static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data);
|
||||
|
@ -307,15 +306,16 @@ static struct usb_driver ati_remote_driver = {
|
|||
/*
|
||||
* ati_remote_dump_input
|
||||
*/
|
||||
static void ati_remote_dump(unsigned char *data, unsigned int len)
|
||||
static void ati_remote_dump(struct device *dev, unsigned char *data,
|
||||
unsigned int len)
|
||||
{
|
||||
if ((len == 1) && (data[0] != (unsigned char)0xff) && (data[0] != 0x00))
|
||||
warn("Weird byte 0x%02x", data[0]);
|
||||
dev_warn(dev, "Weird byte 0x%02x\n", data[0]);
|
||||
else if (len == 4)
|
||||
warn("Weird key %02x %02x %02x %02x",
|
||||
dev_warn(dev, "Weird key %02x %02x %02x %02x\n",
|
||||
data[0], data[1], data[2], data[3]);
|
||||
else
|
||||
warn("Weird data, len=%d %02x %02x %02x %02x %02x %02x ...",
|
||||
dev_warn(dev, "Weird data, len=%d %02x %02x %02x %02x %02x %02x ...\n",
|
||||
len, data[0], data[1], data[2], data[3], data[4], data[5]);
|
||||
}
|
||||
|
||||
|
@ -470,7 +470,7 @@ static void ati_remote_input_report(struct urb *urb)
|
|||
/* Deal with strange looking inputs */
|
||||
if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
|
||||
((data[3] & 0x0f) != 0x00) ) {
|
||||
ati_remote_dump(data, urb->actual_length);
|
||||
ati_remote_dump(&urb->dev->dev, data, urb->actual_length);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -814,7 +814,7 @@ static void ati_remote_disconnect(struct usb_interface *interface)
|
|||
ati_remote = usb_get_intfdata(interface);
|
||||
usb_set_intfdata(interface, NULL);
|
||||
if (!ati_remote) {
|
||||
warn("%s - null device?\n", __func__);
|
||||
dev_warn(&interface->dev, "%s - null device?\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -834,9 +834,11 @@ static int __init ati_remote_init(void)
|
|||
|
||||
result = usb_register(&ati_remote_driver);
|
||||
if (result)
|
||||
err("usb_register error #%d\n", result);
|
||||
printk(KERN_ERR KBUILD_MODNAME
|
||||
": usb_register error #%d\n", result);
|
||||
else
|
||||
info("Registered USB driver " DRIVER_DESC " v. " DRIVER_VERSION);
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
|
||||
DRIVER_DESC "\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -999,7 +999,8 @@ static int __init yealink_dev_init(void)
|
|||
{
|
||||
int ret = usb_register(&yealink_driver);
|
||||
if (ret == 0)
|
||||
info(DRIVER_DESC ":" DRIVER_VERSION);
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
|
||||
DRIVER_DESC "\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -280,7 +280,8 @@ static int __init usb_acecad_init(void)
|
|||
{
|
||||
int result = usb_register(&usb_acecad_driver);
|
||||
if (result == 0)
|
||||
info(DRIVER_VERSION ":" DRIVER_DESC);
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
|
||||
DRIVER_DESC "\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -1706,20 +1706,21 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
|
||||
inputdev = input_allocate_device();
|
||||
if (!aiptek || !inputdev) {
|
||||
warn("aiptek: cannot allocate memory or input device");
|
||||
dev_warn(&intf->dev,
|
||||
"cannot allocate memory or input device\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
|
||||
GFP_ATOMIC, &aiptek->data_dma);
|
||||
if (!aiptek->data) {
|
||||
warn("aiptek: cannot allocate usb buffer");
|
||||
dev_warn(&intf->dev, "cannot allocate usb buffer\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!aiptek->urb) {
|
||||
warn("aiptek: cannot allocate urb");
|
||||
dev_warn(&intf->dev, "cannot allocate urb\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
|
@ -1843,8 +1844,9 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
aiptek->curSetting.programmableDelay = speeds[i];
|
||||
(void)aiptek_program_tablet(aiptek);
|
||||
if (aiptek->inputdev->absmax[ABS_X] > 0) {
|
||||
info("input: Aiptek using %d ms programming speed\n",
|
||||
aiptek->curSetting.programmableDelay);
|
||||
dev_info(&intf->dev,
|
||||
"Aiptek using %d ms programming speed\n",
|
||||
aiptek->curSetting.programmableDelay);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1852,7 +1854,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
/* Murphy says that some day someone will have a tablet that fails the
|
||||
above test. That's you, Frederic Rodrigo */
|
||||
if (i == ARRAY_SIZE(speeds)) {
|
||||
info("input: Aiptek tried all speeds, no sane response");
|
||||
dev_info(&intf->dev,
|
||||
"Aiptek tried all speeds, no sane response\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
|
@ -1864,7 +1867,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
*/
|
||||
err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group);
|
||||
if (err) {
|
||||
warn("aiptek: cannot create sysfs group err: %d", err);
|
||||
dev_warn(&intf->dev, "cannot create sysfs group err: %d\n",
|
||||
err);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
|
@ -1872,7 +1876,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
*/
|
||||
err = input_register_device(aiptek->inputdev);
|
||||
if (err) {
|
||||
warn("aiptek: input_register_device returned err: %d", err);
|
||||
dev_warn(&intf->dev,
|
||||
"input_register_device returned err: %d\n", err);
|
||||
goto fail4;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1922,8 +1927,9 @@ static int __init aiptek_init(void)
|
|||
{
|
||||
int result = usb_register(&aiptek_driver);
|
||||
if (result == 0) {
|
||||
info(DRIVER_VERSION ": " DRIVER_AUTHOR);
|
||||
info(DRIVER_DESC);
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
|
||||
DRIVER_DESC "\n");
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_AUTHOR "\n");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
GTCO digitizer USB driver
|
||||
|
||||
Use the err(), dbg() and info() macros from usb.h for system logging
|
||||
Use the err() and dbg() macros from usb.h for system logging
|
||||
|
||||
TO CHECK: Is pressure done right on report 5?
|
||||
|
||||
|
@ -1010,7 +1010,7 @@ static void gtco_disconnect(struct usb_interface *interface)
|
|||
kfree(gtco);
|
||||
}
|
||||
|
||||
info("gtco driver disconnected");
|
||||
dev_info(&interface->dev, "gtco driver disconnected\n");
|
||||
}
|
||||
|
||||
/* STANDARD MODULE LOAD ROUTINES */
|
||||
|
|
|
@ -215,7 +215,8 @@ static int __init kbtab_init(void)
|
|||
retval = usb_register(&kbtab_driver);
|
||||
if (retval)
|
||||
goto out;
|
||||
info(DRIVER_VERSION ":" DRIVER_DESC);
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
|
||||
DRIVER_DESC "\n");
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -385,7 +385,8 @@ static int __init wacom_init(void)
|
|||
wacom_driver.id_table = get_device_table();
|
||||
result = usb_register(&wacom_driver);
|
||||
if (result == 0)
|
||||
info(DRIVER_VERSION ":" DRIVER_DESC);
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
|
||||
DRIVER_DESC "\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -310,7 +310,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
|
||||
radio->curfreq = f->frequency;
|
||||
if (dsbr100_setfreq(radio, radio->curfreq)==-1)
|
||||
warn("Set frequency failed");
|
||||
dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -361,12 +361,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
|
|||
case V4L2_CID_AUDIO_MUTE:
|
||||
if (ctrl->value) {
|
||||
if (dsbr100_stop(radio) == -1) {
|
||||
warn("Radio did not respond properly");
|
||||
dev_warn(&radio->usbdev->dev,
|
||||
"Radio did not respond properly\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
} else {
|
||||
if (dsbr100_start(radio) == -1) {
|
||||
warn("Radio did not respond properly");
|
||||
dev_warn(&radio->usbdev->dev,
|
||||
"Radio did not respond properly\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +418,8 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
|
|||
radio->muted = 1;
|
||||
|
||||
if (dsbr100_start(radio)<0) {
|
||||
warn("Radio did not start up properly");
|
||||
dev_warn(&radio->usbdev->dev,
|
||||
"Radio did not start up properly\n");
|
||||
radio->users = 0;
|
||||
unlock_kernel();
|
||||
return -EIO;
|
||||
|
@ -501,7 +504,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
|
|||
radio->curfreq = FREQ_MIN*FREQ_MUL;
|
||||
video_set_drvdata(radio->videodev, radio);
|
||||
if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) {
|
||||
warn("Could not register video device");
|
||||
dev_warn(&intf->dev, "Could not register video device\n");
|
||||
video_device_release(radio->videodev);
|
||||
kfree(radio->transfer_buffer);
|
||||
kfree(radio);
|
||||
|
|
|
@ -192,7 +192,7 @@ static void dabusb_iso_complete (struct urb *purb)
|
|||
err("dabusb_iso_complete: invalid len %d", len);
|
||||
}
|
||||
else
|
||||
warn("dabusb_iso_complete: corrupted packet status: %d", purb->iso_frame_desc[i].status);
|
||||
dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status);
|
||||
if (dst != purb->actual_length)
|
||||
err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length);
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
|
|||
}
|
||||
|
||||
if( ret == -EPIPE ) {
|
||||
warn("CLEAR_FEATURE request to remove STALL condition.");
|
||||
dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
|
||||
if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
|
||||
err("request failed");
|
||||
}
|
||||
|
|
|
@ -1098,9 +1098,10 @@ ov51x_clear_snapshot(struct usb_ov511 *ov)
|
|||
reg_w(ov, R51x_SYS_SNAP, 0x02);
|
||||
reg_w(ov, R51x_SYS_SNAP, 0x00);
|
||||
} else if (ov->bclass == BCL_OV518) {
|
||||
warn("snapshot reset not supported yet on OV518(+)");
|
||||
dev_warn(&ov->dev->dev,
|
||||
"snapshot reset not supported yet on OV518(+)\n");
|
||||
} else {
|
||||
err("clear snap: invalid bridge type");
|
||||
dev_err(&ov->dev->dev, "clear snap: invalid bridge type\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1115,14 +1116,16 @@ ov51x_check_snapshot(struct usb_ov511 *ov)
|
|||
if (ov->bclass == BCL_OV511) {
|
||||
ret = reg_r(ov, R51x_SYS_SNAP);
|
||||
if (ret < 0) {
|
||||
err("Error checking snspshot status (%d)", ret);
|
||||
dev_err(&ov->dev->dev,
|
||||
"Error checking snspshot status (%d)\n", ret);
|
||||
} else if (ret & 0x08) {
|
||||
status = 1;
|
||||
}
|
||||
} else if (ov->bclass == BCL_OV518) {
|
||||
warn("snapshot check not supported yet on OV518(+)");
|
||||
dev_warn(&ov->dev->dev,
|
||||
"snapshot check not supported yet on OV518(+)\n");
|
||||
} else {
|
||||
err("check snap: invalid bridge type");
|
||||
dev_err(&ov->dev->dev, "clear snap: invalid bridge type\n");
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -5217,7 +5220,8 @@ saa7111a_configure(struct usb_ov511 *ov)
|
|||
if (ov->bclass == BCL_OV511)
|
||||
reg_w(ov, 0x11, 0x00);
|
||||
else
|
||||
warn("SAA7111A not yet supported with OV518/OV518+");
|
||||
dev_warn(&ov->dev->dev,
|
||||
"SAA7111A not yet supported with OV518/OV518+\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -5456,7 +5460,8 @@ ov518_configure(struct usb_ov511 *ov)
|
|||
* required. OV518 has no uncompressed mode, to save RAM. */
|
||||
if (!dumppix && !ov->compress) {
|
||||
ov->compress = 1;
|
||||
warn("Compression required with OV518...enabling");
|
||||
dev_warn(&ov->dev->dev,
|
||||
"Compression required with OV518...enabling\n");
|
||||
}
|
||||
|
||||
if (ov->bridge == BRG_OV518) {
|
||||
|
|
|
@ -229,7 +229,8 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
|
|||
|
||||
cam->input = input_dev = input_allocate_device();
|
||||
if (!input_dev) {
|
||||
warn("Not enough memory for camera's input device\n");
|
||||
dev_warn(&dev->dev,
|
||||
"Not enough memory for camera's input device\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -243,8 +244,9 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
|
|||
|
||||
error = input_register_device(cam->input);
|
||||
if (error) {
|
||||
warn("Failed to register camera's input device, err: %d\n",
|
||||
error);
|
||||
dev_warn(&dev->dev,
|
||||
"Failed to register camera's input device, err: %d\n",
|
||||
error);
|
||||
input_free_device(cam->input);
|
||||
cam->input = NULL;
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
|
|||
|
||||
cam->input = input_dev = input_allocate_device();
|
||||
if (!input_dev) {
|
||||
warn("insufficient mem for cam input device");
|
||||
dev_warn(&dev->dev, "insufficient mem for cam input device\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -107,8 +107,9 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
|
|||
|
||||
error = input_register_device(cam->input);
|
||||
if (error) {
|
||||
warn("Failed to register camera's input device, err: %d\n",
|
||||
error);
|
||||
dev_warn(&dev->dev,
|
||||
"Failed to register camera's input device, err: %d\n",
|
||||
error);
|
||||
input_free_device(cam->input);
|
||||
cam->input = NULL;
|
||||
}
|
||||
|
@ -587,8 +588,9 @@ static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
|
|||
dataurb->iso_frame_desc[i].offset;
|
||||
|
||||
if (st < 0) {
|
||||
warn("Data error: packet=%d. len=%d. status=%d.",
|
||||
i, n, st);
|
||||
dev_warn(&uvd->dev->dev,
|
||||
"Data error: packet=%d. len=%d. status=%d.\n",
|
||||
i, n, st);
|
||||
uvd->stats.iso_err_count++;
|
||||
continue;
|
||||
}
|
||||
|
@ -699,7 +701,7 @@ static void qcm_stop_data(struct uvd *uvd)
|
|||
|
||||
ret = qcm_camera_off(uvd);
|
||||
if (ret)
|
||||
warn("couldn't turn the cam off.");
|
||||
dev_warn(&uvd->dev->dev, "couldn't turn the cam off.\n");
|
||||
|
||||
uvd->streaming = 0;
|
||||
|
||||
|
|
|
@ -691,7 +691,7 @@ static int alauda_probe(struct usb_interface *interface,
|
|||
al[0].port = ALAUDA_PORT_XD;
|
||||
al[1].port = ALAUDA_PORT_SM;
|
||||
|
||||
info("alauda probed");
|
||||
dev_info(&interface->dev, "alauda probed\n");
|
||||
alauda_check_media(al);
|
||||
alauda_check_media(al+1);
|
||||
|
||||
|
@ -716,7 +716,7 @@ static void alauda_disconnect(struct usb_interface *interface)
|
|||
if (al)
|
||||
kref_put(&al->kref, alauda_delete);
|
||||
|
||||
info("alauda gone");
|
||||
dev_info(&interface->dev, "alauda gone");
|
||||
}
|
||||
|
||||
static struct usb_driver alauda_driver = {
|
||||
|
|
|
@ -540,7 +540,8 @@ static int kingsun_probe(struct usb_interface *intf,
|
|||
if (ret != 0)
|
||||
goto free_mem;
|
||||
|
||||
info("IrDA: Registered KingSun/DonShine device %s", net->name);
|
||||
dev_info(&net->dev, "IrDA: Registered KingSun/DonShine device %s\n",
|
||||
net->name);
|
||||
|
||||
usb_set_intfdata(intf, kingsun);
|
||||
|
||||
|
|
|
@ -801,7 +801,8 @@ static int ks959_probe(struct usb_interface *intf,
|
|||
if (ret != 0)
|
||||
goto free_mem;
|
||||
|
||||
info("IrDA: Registered KingSun KS-959 device %s", net->name);
|
||||
dev_info(&net->dev, "IrDA: Registered KingSun KS-959 device %s\n",
|
||||
net->name);
|
||||
|
||||
usb_set_intfdata(intf, kingsun);
|
||||
|
||||
|
|
|
@ -705,7 +705,8 @@ static int ksdazzle_probe(struct usb_interface *intf,
|
|||
if (ret != 0)
|
||||
goto free_mem;
|
||||
|
||||
info("IrDA: Registered KingSun/Dazzle device %s", net->name);
|
||||
dev_info(&net->dev, "IrDA: Registered KingSun/Dazzle device %s\n",
|
||||
net->name);
|
||||
|
||||
usb_set_intfdata(intf, kingsun);
|
||||
|
||||
|
|
|
@ -506,7 +506,7 @@ static int change_speed(struct stir_cb *stir, unsigned speed)
|
|||
goto found;
|
||||
}
|
||||
|
||||
warn("%s: invalid speed %d", stir->netdev->name, speed);
|
||||
dev_warn(&stir->netdev->dev, "invalid speed %d\n", speed);
|
||||
return -EINVAL;
|
||||
|
||||
found:
|
||||
|
@ -598,8 +598,8 @@ static int fifo_txwait(struct stir_cb *stir, int space)
|
|||
err = read_reg(stir, REG_FIFOCTL, stir->fifo_status,
|
||||
FIFO_REGS_SIZE);
|
||||
if (unlikely(err != FIFO_REGS_SIZE)) {
|
||||
warn("%s: FIFO register read error: %d",
|
||||
stir->netdev->name, err);
|
||||
dev_warn(&stir->netdev->dev,
|
||||
"FIFO register read error: %d\n", err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -783,8 +783,9 @@ static int stir_transmit_thread(void *arg)
|
|||
|
||||
if (unlikely(receive_start(stir))) {
|
||||
if (net_ratelimit())
|
||||
info("%s: receive usb submit failed",
|
||||
stir->netdev->name);
|
||||
dev_info(&dev->dev,
|
||||
"%s: receive usb submit failed\n",
|
||||
stir->netdev->name);
|
||||
stir->receiving = 0;
|
||||
msleep(10);
|
||||
continue;
|
||||
|
@ -836,8 +837,8 @@ static void stir_rcv_irq(struct urb *urb)
|
|||
|
||||
/* in case of error, the kernel thread will restart us */
|
||||
if (err) {
|
||||
warn("%s: usb receive submit error: %d",
|
||||
stir->netdev->name, err);
|
||||
dev_warn(&stir->netdev->dev, "usb receive submit error: %d\n",
|
||||
err);
|
||||
stir->receiving = 0;
|
||||
wake_up_process(stir->thread);
|
||||
}
|
||||
|
@ -1073,7 +1074,8 @@ static int stir_probe(struct usb_interface *intf,
|
|||
if (ret != 0)
|
||||
goto err_out2;
|
||||
|
||||
info("IrDA: Registered SigmaTel device %s", net->name);
|
||||
dev_info(&intf->dev, "IrDA: Registered SigmaTel device %s\n",
|
||||
net->name);
|
||||
|
||||
usb_set_intfdata(intf, stir);
|
||||
|
||||
|
|
|
@ -456,7 +456,7 @@ static void catc_tx_timeout(struct net_device *netdev)
|
|||
{
|
||||
struct catc *catc = netdev_priv(netdev);
|
||||
|
||||
warn("Transmit timed out.");
|
||||
dev_warn(&netdev->dev, "Transmit timed out.\n");
|
||||
usb_unlink_urb(catc->tx_urb);
|
||||
}
|
||||
|
||||
|
@ -847,7 +847,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|||
dbg("64k Memory\n");
|
||||
break;
|
||||
default:
|
||||
warn("Couldn't detect memory size, assuming 32k");
|
||||
dev_warn(&intf->dev,
|
||||
"Couldn't detect memory size, assuming 32k\n");
|
||||
case 0x87654321:
|
||||
catc_set_reg(catc, TxBufCount, 4);
|
||||
catc_set_reg(catc, RxBufCount, 16);
|
||||
|
@ -953,7 +954,8 @@ static int __init catc_init(void)
|
|||
{
|
||||
int result = usb_register(&catc_driver);
|
||||
if (result == 0)
|
||||
info(DRIVER_VERSION " " DRIVER_DESC);
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
|
||||
DRIVER_DESC "\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -832,7 +832,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
|
|||
|
||||
if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
|
||||
{
|
||||
warn("kaweth failed tx_urb %d", res);
|
||||
dev_warn(&net->dev, "kaweth failed tx_urb %d\n", res);
|
||||
skip:
|
||||
kaweth->stats.tx_errors++;
|
||||
|
||||
|
@ -924,7 +924,7 @@ static void kaweth_tx_timeout(struct net_device *net)
|
|||
{
|
||||
struct kaweth_device *kaweth = netdev_priv(net);
|
||||
|
||||
warn("%s: Tx timed out. Resetting.", net->name);
|
||||
dev_warn(&net->dev, "%s: Tx timed out. Resetting.\n", net->name);
|
||||
kaweth->stats.tx_errors++;
|
||||
net->trans_start = jiffies;
|
||||
|
||||
|
@ -1016,10 +1016,10 @@ static int kaweth_probe(
|
|||
*/
|
||||
|
||||
if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) {
|
||||
info("Firmware present in device.");
|
||||
dev_info(&intf->dev, "Firmware present in device.\n");
|
||||
} else {
|
||||
/* Download the firmware */
|
||||
info("Downloading firmware...");
|
||||
dev_info(&intf->dev, "Downloading firmware...\n");
|
||||
kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
|
||||
if ((result = kaweth_download_firmware(kaweth,
|
||||
"kaweth/new_code.bin",
|
||||
|
@ -1061,7 +1061,7 @@ static int kaweth_probe(
|
|||
}
|
||||
|
||||
/* Device will now disappear for a moment... */
|
||||
info("Firmware loaded. I'll be back...");
|
||||
dev_info(&intf->dev, "Firmware loaded. I'll be back...\n");
|
||||
err_fw:
|
||||
free_page((unsigned long)kaweth->firmware_buf);
|
||||
free_netdev(netdev);
|
||||
|
@ -1075,10 +1075,10 @@ err_fw:
|
|||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
info("Statistics collection: %x", kaweth->configuration.statistics_mask);
|
||||
info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
|
||||
info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size));
|
||||
info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
|
||||
dev_info(&intf->dev, "Statistics collection: %x\n", kaweth->configuration.statistics_mask);
|
||||
dev_info(&intf->dev, "Multicast filter limit: %x\n", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
|
||||
dev_info(&intf->dev, "MTU: %d\n", le16_to_cpu(kaweth->configuration.segment_size));
|
||||
dev_info(&intf->dev, "Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
|
||||
(int)kaweth->configuration.hw_addr[0],
|
||||
(int)kaweth->configuration.hw_addr[1],
|
||||
(int)kaweth->configuration.hw_addr[2],
|
||||
|
@ -1174,7 +1174,8 @@ err_fw:
|
|||
goto err_intfdata;
|
||||
}
|
||||
|
||||
info("kaweth interface created at %s", kaweth->net->name);
|
||||
dev_info(&intf->dev, "kaweth interface created at %s\n",
|
||||
kaweth->net->name);
|
||||
|
||||
dbg("Kaweth probe returning.");
|
||||
|
||||
|
@ -1205,11 +1206,11 @@ static void kaweth_disconnect(struct usb_interface *intf)
|
|||
struct kaweth_device *kaweth = usb_get_intfdata(intf);
|
||||
struct net_device *netdev;
|
||||
|
||||
info("Unregistering");
|
||||
dev_info(&intf->dev, "Unregistering\n");
|
||||
|
||||
usb_set_intfdata(intf, NULL);
|
||||
if (!kaweth) {
|
||||
warn("unregistering non-existant device");
|
||||
dev_warn(&intf->dev, "unregistering non-existant device\n");
|
||||
return;
|
||||
}
|
||||
netdev = kaweth->net;
|
||||
|
@ -1269,7 +1270,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
|
|||
|
||||
if (!wait_event_timeout(awd.wqh, awd.done, timeout)) {
|
||||
// timeout
|
||||
warn("usb_control/bulk_msg: timeout");
|
||||
dev_warn(&urb->dev->dev, "usb_control/bulk_msg: timeout\n");
|
||||
usb_kill_urb(urb); // remove urb safely
|
||||
status = -ETIMEDOUT;
|
||||
}
|
||||
|
|
|
@ -221,7 +221,7 @@ static void ctrl_callback(struct urb *urb)
|
|||
case -ENOENT:
|
||||
break;
|
||||
default:
|
||||
warn("ctrl urb status %d", urb->status);
|
||||
dev_warn(&urb->dev->dev, "ctrl urb status %d\n", urb->status);
|
||||
}
|
||||
dev = urb->context;
|
||||
clear_bit(RX_REG_SET, &dev->flags);
|
||||
|
@ -441,10 +441,10 @@ static void read_bulk_callback(struct urb *urb)
|
|||
case -ENOENT:
|
||||
return; /* the urb is in unlink state */
|
||||
case -ETIME:
|
||||
warn("may be reset is needed?..");
|
||||
dev_warn(&urb->dev->dev, "may be reset is needed?..\n");
|
||||
goto goon;
|
||||
default:
|
||||
warn("Rx status %d", urb->status);
|
||||
dev_warn(&urb->dev->dev, "Rx status %d\n", urb->status);
|
||||
goto goon;
|
||||
}
|
||||
|
||||
|
@ -538,7 +538,8 @@ static void write_bulk_callback(struct urb *urb)
|
|||
if (!netif_device_present(dev->netdev))
|
||||
return;
|
||||
if (urb->status)
|
||||
info("%s: Tx status %d", dev->netdev->name, urb->status);
|
||||
dev_info(&urb->dev->dev, "%s: Tx status %d\n",
|
||||
dev->netdev->name, urb->status);
|
||||
dev->netdev->trans_start = jiffies;
|
||||
netif_wake_queue(dev->netdev);
|
||||
}
|
||||
|
@ -561,7 +562,8 @@ static void intr_callback(struct urb *urb)
|
|||
return;
|
||||
/* -EPIPE: should clear the halt */
|
||||
default:
|
||||
info("%s: intr status %d", dev->netdev->name, urb->status);
|
||||
dev_info(&urb->dev->dev, "%s: intr status %d\n",
|
||||
dev->netdev->name, urb->status);
|
||||
goto resubmit;
|
||||
}
|
||||
|
||||
|
@ -665,7 +667,7 @@ static int enable_net_traffic(rtl8150_t * dev)
|
|||
u8 cr, tcr, rcr, msr;
|
||||
|
||||
if (!rtl8150_reset(dev)) {
|
||||
warn("%s - device reset failed", __FUNCTION__);
|
||||
dev_warn(&dev->udev->dev, "device reset failed\n");
|
||||
}
|
||||
/* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */
|
||||
rcr = 0x9e;
|
||||
|
@ -699,7 +701,7 @@ static struct net_device_stats *rtl8150_netdev_stats(struct net_device *dev)
|
|||
static void rtl8150_tx_timeout(struct net_device *netdev)
|
||||
{
|
||||
rtl8150_t *dev = netdev_priv(netdev);
|
||||
warn("%s: Tx timeout.", netdev->name);
|
||||
dev_warn(&netdev->dev, "Tx timeout.\n");
|
||||
usb_unlink_urb(dev->tx_urb);
|
||||
dev->stats.tx_errors++;
|
||||
}
|
||||
|
@ -710,12 +712,12 @@ static void rtl8150_set_multicast(struct net_device *netdev)
|
|||
netif_stop_queue(netdev);
|
||||
if (netdev->flags & IFF_PROMISC) {
|
||||
dev->rx_creg |= cpu_to_le16(0x0001);
|
||||
info("%s: promiscuous mode", netdev->name);
|
||||
dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name);
|
||||
} else if (netdev->mc_count ||
|
||||
(netdev->flags & IFF_ALLMULTI)) {
|
||||
dev->rx_creg &= cpu_to_le16(0xfffe);
|
||||
dev->rx_creg |= cpu_to_le16(0x0002);
|
||||
info("%s: allmulti set", netdev->name);
|
||||
dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name);
|
||||
} else {
|
||||
/* ~RX_MULTICAST, ~RX_PROMISCUOUS */
|
||||
dev->rx_creg &= cpu_to_le16(0x00fc);
|
||||
|
@ -740,7 +742,7 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
|
|||
if (res == -ENODEV)
|
||||
netif_device_detach(dev->netdev);
|
||||
else {
|
||||
warn("failed tx_urb %d\n", res);
|
||||
dev_warn(&netdev->dev, "failed tx_urb %d\n", res);
|
||||
dev->stats.tx_errors++;
|
||||
netif_start_queue(netdev);
|
||||
}
|
||||
|
@ -783,7 +785,7 @@ static int rtl8150_open(struct net_device *netdev)
|
|||
if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) {
|
||||
if (res == -ENODEV)
|
||||
netif_device_detach(dev->netdev);
|
||||
warn("%s: rx_urb submit failed: %d", __FUNCTION__, res);
|
||||
dev_warn(&netdev->dev, "rx_urb submit failed: %d\n", res);
|
||||
return res;
|
||||
}
|
||||
usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
|
||||
|
@ -792,7 +794,7 @@ static int rtl8150_open(struct net_device *netdev)
|
|||
if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) {
|
||||
if (res == -ENODEV)
|
||||
netif_device_detach(dev->netdev);
|
||||
warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
|
||||
dev_warn(&netdev->dev, "intr_urb submit failed: %d\n", res);
|
||||
usb_kill_urb(dev->rx_urb);
|
||||
return res;
|
||||
}
|
||||
|
@ -947,7 +949,7 @@ static int rtl8150_probe(struct usb_interface *intf,
|
|||
goto out2;
|
||||
}
|
||||
|
||||
info("%s: rtl8150 is detected", netdev->name);
|
||||
dev_info(&intf->dev, "%s: rtl8150 is detected\n", netdev->name);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -984,7 +986,8 @@ static void rtl8150_disconnect(struct usb_interface *intf)
|
|||
|
||||
static int __init usb_rtl8150_init(void)
|
||||
{
|
||||
info(DRIVER_DESC " " DRIVER_VERSION);
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
|
||||
DRIVER_DESC "\n");
|
||||
return usb_register(&rtl8150_driver);
|
||||
}
|
||||
|
||||
|
|
|
@ -344,7 +344,7 @@ static void usbatm_extract_one_cell(struct usbatm_data *instance, unsigned char
|
|||
__func__, sarb->len, vcc);
|
||||
/* discard cells already received */
|
||||
skb_trim(sarb, 0);
|
||||
UDSL_ASSERT(sarb->tail + ATM_CELL_PAYLOAD <= sarb->end);
|
||||
UDSL_ASSERT(instance, sarb->tail + ATM_CELL_PAYLOAD <= sarb->end);
|
||||
}
|
||||
|
||||
memcpy(skb_tail_pointer(sarb), source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
|
||||
|
@ -432,7 +432,7 @@ static void usbatm_extract_cells(struct usbatm_data *instance,
|
|||
unsigned char *cell_buf = instance->cell_buf;
|
||||
unsigned int space_left = stride - buf_usage;
|
||||
|
||||
UDSL_ASSERT(buf_usage <= stride);
|
||||
UDSL_ASSERT(instance, buf_usage <= stride);
|
||||
|
||||
if (avail_data >= space_left) {
|
||||
/* add new data and process cell */
|
||||
|
@ -475,7 +475,7 @@ static unsigned int usbatm_write_cells(struct usbatm_data *instance,
|
|||
unsigned int stride = instance->tx_channel.stride;
|
||||
|
||||
vdbg("%s: skb->len=%d, avail_space=%u", __func__, skb->len, avail_space);
|
||||
UDSL_ASSERT(!(avail_space % stride));
|
||||
UDSL_ASSERT(instance, !(avail_space % stride));
|
||||
|
||||
for (bytes_written = 0; bytes_written < avail_space && ctrl->len;
|
||||
bytes_written += stride, target += stride) {
|
||||
|
@ -547,7 +547,7 @@ static void usbatm_rx_process(unsigned long data)
|
|||
if (!urb->iso_frame_desc[i].status) {
|
||||
unsigned int actual_length = urb->iso_frame_desc[i].actual_length;
|
||||
|
||||
UDSL_ASSERT(actual_length <= packet_size);
|
||||
UDSL_ASSERT(instance, actual_length <= packet_size);
|
||||
|
||||
if (!merge_length)
|
||||
merge_start = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
|
||||
|
@ -1188,7 +1188,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
|
|||
struct urb *urb;
|
||||
unsigned int iso_packets = usb_pipeisoc(channel->endpoint) ? channel->buf_size / channel->packet_size : 0;
|
||||
|
||||
UDSL_ASSERT(!usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint));
|
||||
UDSL_ASSERT(instance, !usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint));
|
||||
|
||||
urb = usb_alloc_urb(iso_packets, GFP_KERNEL);
|
||||
if (!urb) {
|
||||
|
|
|
@ -40,9 +40,15 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
#define UDSL_ASSERT(x) BUG_ON(!(x))
|
||||
#define UDSL_ASSERT(instance, x) BUG_ON(!(x))
|
||||
#else
|
||||
#define UDSL_ASSERT(x) do { if (!(x)) warn("failed assertion '%s' at line %d", __stringify(x), __LINE__); } while(0)
|
||||
#define UDSL_ASSERT(instance, x) \
|
||||
do { \
|
||||
if (!(x)) \
|
||||
dev_warn(&(instance)->usb_intf->dev, \
|
||||
"failed assertion '%s' at line %d", \
|
||||
__stringify(x), __LINE__); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#define usb_err(instance, format, arg...) \
|
||||
|
|
|
@ -193,7 +193,7 @@ static int __init xusbatm_init(void)
|
|||
num_vendor != num_product ||
|
||||
num_vendor != num_rx_endpoint ||
|
||||
num_vendor != num_tx_endpoint) {
|
||||
warn("malformed module parameters");
|
||||
printk(KERN_WARNING "xusbatm: malformed module parameters\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,3 +40,13 @@ config USB_WDM
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called cdc-wdm.
|
||||
|
||||
config USB_TMC
|
||||
tristate "USB Test and Measurement Class support"
|
||||
depends on USB
|
||||
help
|
||||
Say Y here if you want to connect a USB device that follows
|
||||
the USB.org specification for USB Test and Measurement devices
|
||||
to your computer's USB port.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called usbtmc.
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
obj-$(CONFIG_USB_ACM) += cdc-acm.o
|
||||
obj-$(CONFIG_USB_PRINTER) += usblp.o
|
||||
obj-$(CONFIG_USB_WDM) += cdc-wdm.o
|
||||
obj-$(CONFIG_USB_TMC) += usbtmc.o
|
||||
|
|
|
@ -326,8 +326,8 @@ exit:
|
|||
usb_mark_last_busy(acm->dev);
|
||||
retval = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
err ("%s - usb_submit_urb failed with result %d",
|
||||
__func__, retval);
|
||||
dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with "
|
||||
"result %d", __func__, retval);
|
||||
}
|
||||
|
||||
/* data interface returns incoming bytes, or we got unthrottled */
|
||||
|
@ -514,7 +514,7 @@ static void acm_waker(struct work_struct *waker)
|
|||
|
||||
rv = usb_autopm_get_interface(acm->control);
|
||||
if (rv < 0) {
|
||||
err("Autopm failure in %s", __func__);
|
||||
dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__);
|
||||
return;
|
||||
}
|
||||
if (acm->delayed_wb) {
|
||||
|
@ -924,7 +924,7 @@ static int acm_probe (struct usb_interface *intf,
|
|||
|
||||
/* normal probing*/
|
||||
if (!buffer) {
|
||||
err("Weird descriptor references\n");
|
||||
dev_err(&intf->dev, "Weird descriptor references\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -934,21 +934,24 @@ static int acm_probe (struct usb_interface *intf,
|
|||
buflen = intf->cur_altsetting->endpoint->extralen;
|
||||
buffer = intf->cur_altsetting->endpoint->extra;
|
||||
} else {
|
||||
err("Zero length descriptor references\n");
|
||||
dev_err(&intf->dev,
|
||||
"Zero length descriptor references\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
while (buflen > 0) {
|
||||
if (buffer [1] != USB_DT_CS_INTERFACE) {
|
||||
err("skipping garbage\n");
|
||||
dev_err(&intf->dev, "skipping garbage\n");
|
||||
goto next_desc;
|
||||
}
|
||||
|
||||
switch (buffer [2]) {
|
||||
case USB_CDC_UNION_TYPE: /* we've found it */
|
||||
if (union_header) {
|
||||
err("More than one union descriptor, skipping ...");
|
||||
dev_err(&intf->dev, "More than one "
|
||||
"union descriptor, "
|
||||
"skipping ...\n");
|
||||
goto next_desc;
|
||||
}
|
||||
union_header = (struct usb_cdc_union_desc *)
|
||||
|
@ -966,7 +969,9 @@ static int acm_probe (struct usb_interface *intf,
|
|||
call_management_function = buffer[3];
|
||||
call_interface_num = buffer[4];
|
||||
if ((call_management_function & 3) != 3)
|
||||
err("This device cannot do calls on its own. It is no modem.");
|
||||
dev_err(&intf->dev, "This device "
|
||||
"cannot do calls on its own. "
|
||||
"It is no modem.\n");
|
||||
break;
|
||||
default:
|
||||
/* there are LOTS more CDC descriptors that
|
||||
|
@ -1051,7 +1056,7 @@ skip_normal_probe:
|
|||
for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
|
||||
|
||||
if (minor == ACM_TTY_MINORS) {
|
||||
err("no more free acm devices");
|
||||
dev_err(&intf->dev, "no more free acm devices\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -1454,7 +1459,8 @@ static int __init acm_init(void)
|
|||
return retval;
|
||||
}
|
||||
|
||||
info(DRIVER_VERSION ":" DRIVER_DESC);
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
|
||||
DRIVER_DESC "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -132,10 +132,12 @@ static void wdm_in_callback(struct urb *urb)
|
|||
"nonzero urb status received: -ESHUTDOWN");
|
||||
break;
|
||||
case -EPIPE:
|
||||
err("nonzero urb status received: -EPIPE");
|
||||
dev_err(&desc->intf->dev,
|
||||
"nonzero urb status received: -EPIPE\n");
|
||||
break;
|
||||
default:
|
||||
err("Unexpected error %d", status);
|
||||
dev_err(&desc->intf->dev,
|
||||
"Unexpected error %d\n", status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -170,16 +172,18 @@ static void wdm_int_callback(struct urb *urb)
|
|||
return; /* unplug */
|
||||
case -EPIPE:
|
||||
set_bit(WDM_INT_STALL, &desc->flags);
|
||||
err("Stall on int endpoint");
|
||||
dev_err(&desc->intf->dev, "Stall on int endpoint\n");
|
||||
goto sw; /* halt is cleared in work */
|
||||
default:
|
||||
err("nonzero urb status received: %d", status);
|
||||
dev_err(&desc->intf->dev,
|
||||
"nonzero urb status received: %d\n", status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (urb->actual_length < sizeof(struct usb_cdc_notification)) {
|
||||
err("wdm_int_callback - %d bytes", urb->actual_length);
|
||||
dev_err(&desc->intf->dev, "wdm_int_callback - %d bytes\n",
|
||||
urb->actual_length);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -198,7 +202,8 @@ static void wdm_int_callback(struct urb *urb)
|
|||
goto exit;
|
||||
default:
|
||||
clear_bit(WDM_POLL_RUNNING, &desc->flags);
|
||||
err("unknown notification %d received: index %d len %d",
|
||||
dev_err(&desc->intf->dev,
|
||||
"unknown notification %d received: index %d len %d\n",
|
||||
dr->bNotificationType, dr->wIndex, dr->wLength);
|
||||
goto exit;
|
||||
}
|
||||
|
@ -236,14 +241,16 @@ static void wdm_int_callback(struct urb *urb)
|
|||
sw:
|
||||
rv = schedule_work(&desc->rxwork);
|
||||
if (rv)
|
||||
err("Cannot schedule work");
|
||||
dev_err(&desc->intf->dev,
|
||||
"Cannot schedule work\n");
|
||||
}
|
||||
}
|
||||
exit:
|
||||
rv = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (rv)
|
||||
err("%s - usb_submit_urb failed with result %d",
|
||||
__func__, rv);
|
||||
dev_err(&desc->intf->dev,
|
||||
"%s - usb_submit_urb failed with result %d\n",
|
||||
__func__, rv);
|
||||
|
||||
}
|
||||
|
||||
|
@ -353,7 +360,7 @@ static ssize_t wdm_write
|
|||
if (rv < 0) {
|
||||
kfree(buf);
|
||||
clear_bit(WDM_IN_USE, &desc->flags);
|
||||
err("Tx URB error: %d", rv);
|
||||
dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
|
||||
} else {
|
||||
dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d",
|
||||
req->wIndex);
|
||||
|
@ -401,7 +408,8 @@ retry:
|
|||
int t = desc->rerr;
|
||||
desc->rerr = 0;
|
||||
spin_unlock_irq(&desc->iuspin);
|
||||
err("reading had resulted in %d", t);
|
||||
dev_err(&desc->intf->dev,
|
||||
"reading had resulted in %d\n", t);
|
||||
rv = -EIO;
|
||||
goto err;
|
||||
}
|
||||
|
@ -440,7 +448,7 @@ retry:
|
|||
err:
|
||||
mutex_unlock(&desc->rlock);
|
||||
if (rv < 0)
|
||||
err("wdm_read: exit error");
|
||||
dev_err(&desc->intf->dev, "wdm_read: exit error\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -450,7 +458,8 @@ static int wdm_flush(struct file *file, fl_owner_t id)
|
|||
|
||||
wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags));
|
||||
if (desc->werr < 0)
|
||||
err("Error in flush path: %d", desc->werr);
|
||||
dev_err(&desc->intf->dev, "Error in flush path: %d\n",
|
||||
desc->werr);
|
||||
|
||||
return desc->werr;
|
||||
}
|
||||
|
@ -502,7 +511,7 @@ static int wdm_open(struct inode *inode, struct file *file)
|
|||
|
||||
rv = usb_autopm_get_interface(desc->intf);
|
||||
if (rv < 0) {
|
||||
err("Error autopm - %d", rv);
|
||||
dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
|
||||
goto out;
|
||||
}
|
||||
intf->needs_remote_wakeup = 1;
|
||||
|
@ -512,7 +521,8 @@ static int wdm_open(struct inode *inode, struct file *file)
|
|||
rv = usb_submit_urb(desc->validity, GFP_KERNEL);
|
||||
if (rv < 0) {
|
||||
desc->count--;
|
||||
err("Error submitting int urb - %d", rv);
|
||||
dev_err(&desc->intf->dev,
|
||||
"Error submitting int urb - %d\n", rv);
|
||||
}
|
||||
} else {
|
||||
rv = 0;
|
||||
|
@ -600,7 +610,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
|
||||
while (buflen > 0) {
|
||||
if (buffer [1] != USB_DT_CS_INTERFACE) {
|
||||
err("skipping garbage");
|
||||
dev_err(&intf->dev, "skipping garbage\n");
|
||||
goto next_desc;
|
||||
}
|
||||
|
||||
|
@ -614,7 +624,8 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
"Finding maximum buffer length: %d", maxcom);
|
||||
break;
|
||||
default:
|
||||
err("Ignoring extra header, type %d, length %d",
|
||||
dev_err(&intf->dev,
|
||||
"Ignoring extra header, type %d, length %d\n",
|
||||
buffer[2], buffer[0]);
|
||||
break;
|
||||
}
|
||||
|
@ -772,7 +783,8 @@ static int recover_from_urb_loss(struct wdm_device *desc)
|
|||
if (desc->count) {
|
||||
rv = usb_submit_urb(desc->validity, GFP_NOIO);
|
||||
if (rv < 0)
|
||||
err("Error resume submitting int urb - %d", rv);
|
||||
dev_err(&desc->intf->dev,
|
||||
"Error resume submitting int urb - %d\n", rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -593,8 +593,9 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
err = usblp_hp_channel_change_request(usblp,
|
||||
arg, &newChannel);
|
||||
if (err < 0) {
|
||||
err("usblp%d: error = %d setting "
|
||||
"HP channel",
|
||||
dev_err(&usblp->dev->dev,
|
||||
"usblp%d: error = %d setting "
|
||||
"HP channel\n",
|
||||
usblp->minor, err);
|
||||
retval = -EIO;
|
||||
goto done;
|
||||
|
@ -1076,15 +1077,16 @@ static int usblp_probe(struct usb_interface *intf,
|
|||
const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_device *dev = interface_to_usbdev (intf);
|
||||
struct usblp *usblp = NULL;
|
||||
struct usblp *usblp;
|
||||
int protocol;
|
||||
int retval;
|
||||
|
||||
/* Malloc and start initializing usblp structure so we can use it
|
||||
* directly. */
|
||||
if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) {
|
||||
usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL);
|
||||
if (!usblp) {
|
||||
retval = -ENOMEM;
|
||||
goto abort;
|
||||
goto abort_ret;
|
||||
}
|
||||
usblp->dev = dev;
|
||||
mutex_init(&usblp->wmut);
|
||||
|
@ -1179,12 +1181,11 @@ abort_intfdata:
|
|||
usb_set_intfdata (intf, NULL);
|
||||
device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
|
||||
abort:
|
||||
if (usblp) {
|
||||
kfree(usblp->readbuf);
|
||||
kfree(usblp->statusbuf);
|
||||
kfree(usblp->device_id_string);
|
||||
kfree(usblp);
|
||||
}
|
||||
kfree(usblp->readbuf);
|
||||
kfree(usblp->statusbuf);
|
||||
kfree(usblp->device_id_string);
|
||||
kfree(usblp);
|
||||
abort_ret:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -1345,7 +1346,7 @@ static void usblp_disconnect(struct usb_interface *intf)
|
|||
usb_deregister_dev(intf, &usblp_class);
|
||||
|
||||
if (!usblp || !usblp->dev) {
|
||||
err("bogus disconnect");
|
||||
dev_err(&intf->dev, "bogus disconnect\n");
|
||||
BUG ();
|
||||
}
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -134,5 +134,5 @@ config USB_OTG_BLACKLIST_HUB
|
|||
If you say Y here, then Linux will refuse to enumerate
|
||||
external hubs. OTG hosts are allowed to reduce hardware
|
||||
and software costs by not supporting external hubs. So
|
||||
are "Emedded Hosts" that don't offer OTG support.
|
||||
are "Embedded Hosts" that don't offer OTG support.
|
||||
|
||||
|
|
|
@ -413,7 +413,8 @@ static void driver_disconnect(struct usb_interface *intf)
|
|||
if (likely(ifnum < 8*sizeof(ps->ifclaimed)))
|
||||
clear_bit(ifnum, &ps->ifclaimed);
|
||||
else
|
||||
warn("interface number %u out of range", ifnum);
|
||||
dev_warn(&intf->dev, "interface number %u out of range\n",
|
||||
ifnum);
|
||||
|
||||
usb_set_intfdata(intf, NULL);
|
||||
|
||||
|
@ -624,6 +625,8 @@ static int usbdev_open(struct inode *inode, struct file *file)
|
|||
smp_wmb();
|
||||
list_add_tail(&ps->list, &dev->filelist);
|
||||
file->private_data = ps;
|
||||
snoop(&dev->dev, "opened by process %d: %s\n", task_pid_nr(current),
|
||||
current->comm);
|
||||
out:
|
||||
if (ret) {
|
||||
kfree(ps);
|
||||
|
@ -1774,19 +1777,20 @@ int __init usb_devio_init(void)
|
|||
retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,
|
||||
"usb_device");
|
||||
if (retval) {
|
||||
err("unable to register minors for usb_device");
|
||||
printk(KERN_ERR "Unable to register minors for usb_device\n");
|
||||
goto out;
|
||||
}
|
||||
cdev_init(&usb_device_cdev, &usbdev_file_operations);
|
||||
retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
|
||||
if (retval) {
|
||||
err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
|
||||
printk(KERN_ERR "Unable to get usb_device major %d\n",
|
||||
USB_DEVICE_MAJOR);
|
||||
goto error_cdev;
|
||||
}
|
||||
#ifdef CONFIG_USB_DEVICE_CLASS
|
||||
usb_classdev_class = class_create(THIS_MODULE, "usb_device");
|
||||
if (IS_ERR(usb_classdev_class)) {
|
||||
err("unable to register usb_device class");
|
||||
printk(KERN_ERR "Unable to register usb_device class\n");
|
||||
retval = PTR_ERR(usb_classdev_class);
|
||||
cdev_del(&usb_device_cdev);
|
||||
usb_classdev_class = NULL;
|
||||
|
|
|
@ -1070,7 +1070,8 @@ static int autosuspend_check(struct usb_device *udev, int reschedule)
|
|||
struct usb_driver *driver;
|
||||
|
||||
driver = to_usb_driver(intf->dev.driver);
|
||||
if (!driver->reset_resume)
|
||||
if (!driver->reset_resume ||
|
||||
intf->needs_remote_wakeup)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,7 +169,8 @@ static int usb_endpoint_major_init(void)
|
|||
error = alloc_chrdev_region(&dev, 0, MAX_ENDPOINT_MINORS,
|
||||
"usb_endpoint");
|
||||
if (error) {
|
||||
err("unable to get a dynamic major for usb endpoints");
|
||||
printk(KERN_ERR "Unable to get a dynamic major for "
|
||||
"usb endpoints.\n");
|
||||
return error;
|
||||
}
|
||||
usb_endpoint_major = MAJOR(dev);
|
||||
|
|
|
@ -86,7 +86,7 @@ static int init_usb_class(void)
|
|||
usb_class->class = class_create(THIS_MODULE, "usb");
|
||||
if (IS_ERR(usb_class->class)) {
|
||||
result = IS_ERR(usb_class->class);
|
||||
err("class_create failed for usb devices");
|
||||
printk(KERN_ERR "class_create failed for usb devices\n");
|
||||
kfree(usb_class);
|
||||
usb_class = NULL;
|
||||
}
|
||||
|
@ -115,7 +115,8 @@ int usb_major_init(void)
|
|||
|
||||
error = register_chrdev(USB_MAJOR, "usb", &usb_fops);
|
||||
if (error)
|
||||
err("unable to get major %d for usb devices", USB_MAJOR);
|
||||
printk(KERN_ERR "Unable to get major %d for usb devices\n",
|
||||
USB_MAJOR);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,10 @@
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* Keep track of which host controller drivers are loaded */
|
||||
unsigned long usb_hcds_loaded;
|
||||
EXPORT_SYMBOL_GPL(usb_hcds_loaded);
|
||||
|
||||
/* host controllers we manage */
|
||||
LIST_HEAD (usb_bus_list);
|
||||
EXPORT_SYMBOL_GPL (usb_bus_list);
|
||||
|
|
|
@ -482,4 +482,10 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
|
|||
*/
|
||||
extern struct rw_semaphore ehci_cf_port_reset_rwsem;
|
||||
|
||||
/* Keep track of which host controller drivers are loaded */
|
||||
#define USB_UHCI_LOADED 0
|
||||
#define USB_OHCI_LOADED 1
|
||||
#define USB_EHCI_LOADED 2
|
||||
extern unsigned long usb_hcds_loaded;
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
|
|
@ -77,6 +77,7 @@ struct usb_hub {
|
|||
unsigned has_indicators:1;
|
||||
u8 indicator[USB_MAXCHILDREN];
|
||||
struct delayed_work leds;
|
||||
struct delayed_work init_work;
|
||||
};
|
||||
|
||||
|
||||
|
@ -99,6 +100,15 @@ static int blinkenlights = 0;
|
|||
module_param (blinkenlights, bool, S_IRUGO);
|
||||
MODULE_PARM_DESC (blinkenlights, "true to cycle leds on hubs");
|
||||
|
||||
/*
|
||||
* Device SATA8000 FW1.0 from DATAST0R Technology Corp requires about
|
||||
* 10 seconds to send reply for the initial 64-byte descriptor request.
|
||||
*/
|
||||
/* define initial 64-byte descriptor request timeout in milliseconds */
|
||||
static int initial_descriptor_timeout = USB_CTRL_GET_TIMEOUT;
|
||||
module_param(initial_descriptor_timeout, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(initial_descriptor_timeout, "initial 64-byte descriptor request timeout in milliseconds (default 5000 - 5.0 seconds)");
|
||||
|
||||
/*
|
||||
* As of 2.6.10 we introduce a new USB device initialization scheme which
|
||||
* closely resembles the way Windows works. Hopefully it will be compatible
|
||||
|
@ -515,10 +525,14 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer);
|
||||
|
||||
static void hub_power_on(struct usb_hub *hub)
|
||||
/* If do_delay is false, return the number of milliseconds the caller
|
||||
* needs to delay.
|
||||
*/
|
||||
static unsigned hub_power_on(struct usb_hub *hub, bool do_delay)
|
||||
{
|
||||
int port1;
|
||||
unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
|
||||
unsigned delay;
|
||||
u16 wHubCharacteristics =
|
||||
le16_to_cpu(hub->descriptor->wHubCharacteristics);
|
||||
|
||||
|
@ -537,7 +551,10 @@ static void hub_power_on(struct usb_hub *hub)
|
|||
set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER);
|
||||
|
||||
/* Wait at least 100 msec for power to become stable */
|
||||
msleep(max(pgood_delay, (unsigned) 100));
|
||||
delay = max(pgood_delay, (unsigned) 100);
|
||||
if (do_delay)
|
||||
msleep(delay);
|
||||
return delay;
|
||||
}
|
||||
|
||||
static int hub_hub_status(struct usb_hub *hub,
|
||||
|
@ -599,21 +616,55 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
|
|||
}
|
||||
|
||||
enum hub_activation_type {
|
||||
HUB_INIT, HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME
|
||||
HUB_INIT, HUB_INIT2, HUB_INIT3,
|
||||
HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME,
|
||||
};
|
||||
|
||||
static void hub_init_func2(struct work_struct *ws);
|
||||
static void hub_init_func3(struct work_struct *ws);
|
||||
|
||||
static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
||||
{
|
||||
struct usb_device *hdev = hub->hdev;
|
||||
int port1;
|
||||
int status;
|
||||
bool need_debounce_delay = false;
|
||||
unsigned delay;
|
||||
|
||||
/* Continue a partial initialization */
|
||||
if (type == HUB_INIT2)
|
||||
goto init2;
|
||||
if (type == HUB_INIT3)
|
||||
goto init3;
|
||||
|
||||
/* After a resume, port power should still be on.
|
||||
* For any other type of activation, turn it on.
|
||||
*/
|
||||
if (type != HUB_RESUME)
|
||||
hub_power_on(hub);
|
||||
if (type != HUB_RESUME) {
|
||||
|
||||
/* Speed up system boot by using a delayed_work for the
|
||||
* hub's initial power-up delays. This is pretty awkward
|
||||
* and the implementation looks like a home-brewed sort of
|
||||
* setjmp/longjmp, but it saves at least 100 ms for each
|
||||
* root hub (assuming usbcore is compiled into the kernel
|
||||
* rather than as a module). It adds up.
|
||||
*
|
||||
* This can't be done for HUB_RESUME or HUB_RESET_RESUME
|
||||
* because for those activation types the ports have to be
|
||||
* operational when we return. In theory this could be done
|
||||
* for HUB_POST_RESET, but it's easier not to.
|
||||
*/
|
||||
if (type == HUB_INIT) {
|
||||
delay = hub_power_on(hub, false);
|
||||
PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func2);
|
||||
schedule_delayed_work(&hub->init_work,
|
||||
msecs_to_jiffies(delay));
|
||||
return; /* Continues at init2: below */
|
||||
} else {
|
||||
hub_power_on(hub, true);
|
||||
}
|
||||
}
|
||||
init2:
|
||||
|
||||
/* Check each port and set hub->change_bits to let khubd know
|
||||
* which ports need attention.
|
||||
|
@ -692,9 +743,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
|||
* If any port-status changes do occur during this delay, khubd
|
||||
* will see them later and handle them normally.
|
||||
*/
|
||||
if (need_debounce_delay)
|
||||
msleep(HUB_DEBOUNCE_STABLE);
|
||||
if (need_debounce_delay) {
|
||||
delay = HUB_DEBOUNCE_STABLE;
|
||||
|
||||
/* Don't do a long sleep inside a workqueue routine */
|
||||
if (type == HUB_INIT2) {
|
||||
PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3);
|
||||
schedule_delayed_work(&hub->init_work,
|
||||
msecs_to_jiffies(delay));
|
||||
return; /* Continues at init3: below */
|
||||
} else {
|
||||
msleep(delay);
|
||||
}
|
||||
}
|
||||
init3:
|
||||
hub->quiescing = 0;
|
||||
|
||||
status = usb_submit_urb(hub->urb, GFP_NOIO);
|
||||
|
@ -707,6 +769,21 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
|||
kick_khubd(hub);
|
||||
}
|
||||
|
||||
/* Implement the continuations for the delays above */
|
||||
static void hub_init_func2(struct work_struct *ws)
|
||||
{
|
||||
struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work);
|
||||
|
||||
hub_activate(hub, HUB_INIT2);
|
||||
}
|
||||
|
||||
static void hub_init_func3(struct work_struct *ws)
|
||||
{
|
||||
struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work);
|
||||
|
||||
hub_activate(hub, HUB_INIT3);
|
||||
}
|
||||
|
||||
enum hub_quiescing_type {
|
||||
HUB_DISCONNECT, HUB_PRE_RESET, HUB_SUSPEND
|
||||
};
|
||||
|
@ -716,6 +793,8 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
|
|||
struct usb_device *hdev = hub->hdev;
|
||||
int i;
|
||||
|
||||
cancel_delayed_work_sync(&hub->init_work);
|
||||
|
||||
/* khubd and related activity won't re-trigger */
|
||||
hub->quiescing = 1;
|
||||
|
||||
|
@ -1099,6 +1178,7 @@ descriptor_error:
|
|||
hub->intfdev = &intf->dev;
|
||||
hub->hdev = hdev;
|
||||
INIT_DELAYED_WORK(&hub->leds, led_work);
|
||||
INIT_DELAYED_WORK(&hub->init_work, NULL);
|
||||
usb_get_intf(intf);
|
||||
|
||||
usb_set_intfdata (intf, hub);
|
||||
|
@ -2467,7 +2547,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
|
|||
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
|
||||
USB_DT_DEVICE << 8, 0,
|
||||
buf, GET_DESCRIPTOR_BUFSIZE,
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
initial_descriptor_timeout);
|
||||
switch (buf->bMaxPacketSize0) {
|
||||
case 8: case 16: case 32: case 64: case 255:
|
||||
if (buf->bDescriptorType ==
|
||||
|
@ -3035,7 +3115,7 @@ static void hub_events(void)
|
|||
i);
|
||||
clear_port_feature(hdev, i,
|
||||
USB_PORT_FEAT_C_OVER_CURRENT);
|
||||
hub_power_on(hub);
|
||||
hub_power_on(hub, true);
|
||||
}
|
||||
|
||||
if (portchange & USB_PORT_STAT_C_RESET) {
|
||||
|
@ -3070,7 +3150,7 @@ static void hub_events(void)
|
|||
dev_dbg (hub_dev, "overcurrent change\n");
|
||||
msleep(500); /* Cool down */
|
||||
clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
|
||||
hub_power_on(hub);
|
||||
hub_power_on(hub, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -180,8 +180,8 @@ static int parse_options(struct super_block *s, char *data)
|
|||
listmode = option & S_IRWXUGO;
|
||||
break;
|
||||
default:
|
||||
err("usbfs: unrecognised mount option \"%s\" "
|
||||
"or missing value\n", p);
|
||||
printk(KERN_ERR "usbfs: unrecognised mount option "
|
||||
"\"%s\" or missing value\n", p);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +240,9 @@ static void update_sb(struct super_block *sb)
|
|||
update_special(bus);
|
||||
break;
|
||||
default:
|
||||
warn("Unknown node %s mode %x found on remount!\n",bus->d_name.name,bus->d_inode->i_mode);
|
||||
printk(KERN_WARNING "usbfs: Unknown node %s "
|
||||
"mode %x found on remount!\n",
|
||||
bus->d_name.name, bus->d_inode->i_mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -259,7 +261,7 @@ static int remount(struct super_block *sb, int *flags, char *data)
|
|||
return 0;
|
||||
|
||||
if (parse_options(sb, data)) {
|
||||
warn("usbfs: mount parameter error:");
|
||||
printk(KERN_WARNING "usbfs: mount parameter error.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -599,7 +601,7 @@ static int create_special_files (void)
|
|||
/* create the devices special file */
|
||||
retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count);
|
||||
if (retval) {
|
||||
err ("Unable to get usbfs mount");
|
||||
printk(KERN_ERR "Unable to get usbfs mount\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -611,7 +613,7 @@ static int create_special_files (void)
|
|||
NULL, &usbfs_devices_fops,
|
||||
listuid, listgid);
|
||||
if (devices_usbfs_dentry == NULL) {
|
||||
err ("Unable to create devices usbfs file");
|
||||
printk(KERN_ERR "Unable to create devices usbfs file\n");
|
||||
retval = -ENODEV;
|
||||
goto error_clean_mounts;
|
||||
}
|
||||
|
@ -663,7 +665,7 @@ static void usbfs_add_bus(struct usb_bus *bus)
|
|||
bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
|
||||
bus, NULL, busuid, busgid);
|
||||
if (bus->usbfs_dentry == NULL) {
|
||||
err ("error creating usbfs bus entry");
|
||||
printk(KERN_ERR "Error creating usbfs bus entry\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -694,7 +696,7 @@ static void usbfs_add_device(struct usb_device *dev)
|
|||
&usbdev_file_operations,
|
||||
devuid, devgid);
|
||||
if (dev->usbfs_dentry == NULL) {
|
||||
err ("error creating usbfs device entry");
|
||||
printk(KERN_ERR "Error creating usbfs device entry\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1204,7 +1204,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
|
|||
|
||||
alt = usb_altnum_to_altsetting(iface, alternate);
|
||||
if (!alt) {
|
||||
warn("selecting invalid altsetting %d", alternate);
|
||||
dev_warn(&dev->dev, "selecting invalid altsetting %d",
|
||||
alternate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -743,6 +743,29 @@ static ssize_t show_modalias(struct device *dev,
|
|||
}
|
||||
static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
|
||||
|
||||
static ssize_t show_supports_autosuspend(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_interface *intf;
|
||||
struct usb_device *udev;
|
||||
int ret;
|
||||
|
||||
intf = to_usb_interface(dev);
|
||||
udev = interface_to_usbdev(intf);
|
||||
|
||||
usb_lock_device(udev);
|
||||
/* Devices will be autosuspended even when an interface isn't claimed */
|
||||
if (!intf->dev.driver ||
|
||||
to_usb_driver(intf->dev.driver)->supports_autosuspend)
|
||||
ret = sprintf(buf, "%u\n", 1);
|
||||
else
|
||||
ret = sprintf(buf, "%u\n", 0);
|
||||
usb_unlock_device(udev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static DEVICE_ATTR(supports_autosuspend, S_IRUGO, show_supports_autosuspend, NULL);
|
||||
|
||||
static struct attribute *intf_attrs[] = {
|
||||
&dev_attr_bInterfaceNumber.attr,
|
||||
&dev_attr_bAlternateSetting.attr,
|
||||
|
@ -751,6 +774,7 @@ static struct attribute *intf_attrs[] = {
|
|||
&dev_attr_bInterfaceSubClass.attr,
|
||||
&dev_attr_bInterfaceProtocol.attr,
|
||||
&dev_attr_modalias.attr,
|
||||
&dev_attr_supports_autosuspend.attr,
|
||||
NULL,
|
||||
};
|
||||
static struct attribute_group intf_attr_grp = {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#define to_urb(d) container_of(d, struct urb, kref)
|
||||
|
||||
static DEFINE_SPINLOCK(usb_reject_lock);
|
||||
|
||||
static void urb_destroy(struct kref *kref)
|
||||
{
|
||||
struct urb *urb = to_urb(kref);
|
||||
|
@ -68,7 +70,7 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
|
|||
iso_packets * sizeof(struct usb_iso_packet_descriptor),
|
||||
mem_flags);
|
||||
if (!urb) {
|
||||
err("alloc_urb: kmalloc failed");
|
||||
printk(KERN_ERR "alloc_urb: kmalloc failed\n");
|
||||
return NULL;
|
||||
}
|
||||
usb_init_urb(urb);
|
||||
|
@ -127,6 +129,13 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor)
|
|||
usb_get_urb(urb);
|
||||
list_add_tail(&urb->anchor_list, &anchor->urb_list);
|
||||
urb->anchor = anchor;
|
||||
|
||||
if (unlikely(anchor->poisoned)) {
|
||||
spin_lock(&usb_reject_lock);
|
||||
urb->reject++;
|
||||
spin_unlock(&usb_reject_lock);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&anchor->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_anchor_urb);
|
||||
|
@ -398,7 +407,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
|
|||
|
||||
/* fail if submitter gave bogus flags */
|
||||
if (urb->transfer_flags != orig_flags) {
|
||||
err("BOGUS urb flags, %x --> %x",
|
||||
dev_err(&dev->dev, "BOGUS urb flags, %x --> %x\n",
|
||||
orig_flags, urb->transfer_flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -544,24 +553,69 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb);
|
|||
*/
|
||||
void usb_kill_urb(struct urb *urb)
|
||||
{
|
||||
static DEFINE_MUTEX(reject_mutex);
|
||||
|
||||
might_sleep();
|
||||
if (!(urb && urb->dev && urb->ep))
|
||||
return;
|
||||
mutex_lock(&reject_mutex);
|
||||
spin_lock_irq(&usb_reject_lock);
|
||||
++urb->reject;
|
||||
mutex_unlock(&reject_mutex);
|
||||
spin_unlock_irq(&usb_reject_lock);
|
||||
|
||||
usb_hcd_unlink_urb(urb, -ENOENT);
|
||||
wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0);
|
||||
|
||||
mutex_lock(&reject_mutex);
|
||||
spin_lock_irq(&usb_reject_lock);
|
||||
--urb->reject;
|
||||
mutex_unlock(&reject_mutex);
|
||||
spin_unlock_irq(&usb_reject_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_kill_urb);
|
||||
|
||||
/**
|
||||
* usb_poison_urb - reliably kill a transfer and prevent further use of an URB
|
||||
* @urb: pointer to URB describing a previously submitted request,
|
||||
* may be NULL
|
||||
*
|
||||
* This routine cancels an in-progress request. It is guaranteed that
|
||||
* upon return all completion handlers will have finished and the URB
|
||||
* will be totally idle and cannot be reused. These features make
|
||||
* this an ideal way to stop I/O in a disconnect() callback.
|
||||
* If the request has not already finished or been unlinked
|
||||
* the completion handler will see urb->status == -ENOENT.
|
||||
*
|
||||
* After and while the routine runs, attempts to resubmit the URB will fail
|
||||
* with error -EPERM. Thus even if the URB's completion handler always
|
||||
* tries to resubmit, it will not succeed and the URB will become idle.
|
||||
*
|
||||
* This routine may not be used in an interrupt context (such as a bottom
|
||||
* half or a completion handler), or when holding a spinlock, or in other
|
||||
* situations where the caller can't schedule().
|
||||
*/
|
||||
void usb_poison_urb(struct urb *urb)
|
||||
{
|
||||
might_sleep();
|
||||
if (!(urb && urb->dev && urb->ep))
|
||||
return;
|
||||
spin_lock_irq(&usb_reject_lock);
|
||||
++urb->reject;
|
||||
spin_unlock_irq(&usb_reject_lock);
|
||||
|
||||
usb_hcd_unlink_urb(urb, -ENOENT);
|
||||
wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_poison_urb);
|
||||
|
||||
void usb_unpoison_urb(struct urb *urb)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!urb)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&usb_reject_lock, flags);
|
||||
--urb->reject;
|
||||
spin_unlock_irqrestore(&usb_reject_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_unpoison_urb);
|
||||
|
||||
/**
|
||||
* usb_kill_anchored_urbs - cancel transfer requests en masse
|
||||
* @anchor: anchor the requests are bound to
|
||||
|
@ -589,6 +643,35 @@ void usb_kill_anchored_urbs(struct usb_anchor *anchor)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);
|
||||
|
||||
|
||||
/**
|
||||
* usb_poison_anchored_urbs - cease all traffic from an anchor
|
||||
* @anchor: anchor the requests are bound to
|
||||
*
|
||||
* this allows all outstanding URBs to be poisoned starting
|
||||
* from the back of the queue. Newly added URBs will also be
|
||||
* poisoned
|
||||
*/
|
||||
void usb_poison_anchored_urbs(struct usb_anchor *anchor)
|
||||
{
|
||||
struct urb *victim;
|
||||
|
||||
spin_lock_irq(&anchor->lock);
|
||||
anchor->poisoned = 1;
|
||||
while (!list_empty(&anchor->urb_list)) {
|
||||
victim = list_entry(anchor->urb_list.prev, struct urb,
|
||||
anchor_list);
|
||||
/* we must make sure the URB isn't freed before we kill it*/
|
||||
usb_get_urb(victim);
|
||||
spin_unlock_irq(&anchor->lock);
|
||||
/* this will unanchor the URB */
|
||||
usb_poison_urb(victim);
|
||||
usb_put_urb(victim);
|
||||
spin_lock_irq(&anchor->lock);
|
||||
}
|
||||
spin_unlock_irq(&anchor->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs);
|
||||
/**
|
||||
* usb_unlink_anchored_urbs - asynchronously cancel transfer requests en masse
|
||||
* @anchor: anchor the requests are bound to
|
||||
|
@ -633,3 +716,73 @@ int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
|
|||
msecs_to_jiffies(timeout));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout);
|
||||
|
||||
/**
|
||||
* usb_get_from_anchor - get an anchor's oldest urb
|
||||
* @anchor: the anchor whose urb you want
|
||||
*
|
||||
* this will take the oldest urb from an anchor,
|
||||
* unanchor and return it
|
||||
*/
|
||||
struct urb *usb_get_from_anchor(struct usb_anchor *anchor)
|
||||
{
|
||||
struct urb *victim;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&anchor->lock, flags);
|
||||
if (!list_empty(&anchor->urb_list)) {
|
||||
victim = list_entry(anchor->urb_list.next, struct urb,
|
||||
anchor_list);
|
||||
usb_get_urb(victim);
|
||||
spin_unlock_irqrestore(&anchor->lock, flags);
|
||||
usb_unanchor_urb(victim);
|
||||
} else {
|
||||
spin_unlock_irqrestore(&anchor->lock, flags);
|
||||
victim = NULL;
|
||||
}
|
||||
|
||||
return victim;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(usb_get_from_anchor);
|
||||
|
||||
/**
|
||||
* usb_scuttle_anchored_urbs - unanchor all an anchor's urbs
|
||||
* @anchor: the anchor whose urbs you want to unanchor
|
||||
*
|
||||
* use this to get rid of all an anchor's urbs
|
||||
*/
|
||||
void usb_scuttle_anchored_urbs(struct usb_anchor *anchor)
|
||||
{
|
||||
struct urb *victim;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&anchor->lock, flags);
|
||||
while (!list_empty(&anchor->urb_list)) {
|
||||
victim = list_entry(anchor->urb_list.prev, struct urb,
|
||||
anchor_list);
|
||||
usb_get_urb(victim);
|
||||
spin_unlock_irqrestore(&anchor->lock, flags);
|
||||
/* this may free the URB */
|
||||
usb_unanchor_urb(victim);
|
||||
usb_put_urb(victim);
|
||||
spin_lock_irqsave(&anchor->lock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&anchor->lock, flags);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(usb_scuttle_anchored_urbs);
|
||||
|
||||
/**
|
||||
* usb_anchor_empty - is an anchor empty
|
||||
* @anchor: the anchor you want to query
|
||||
*
|
||||
* returns 1 if the anchor has no urbs associated with it
|
||||
*/
|
||||
int usb_anchor_empty(struct usb_anchor *anchor)
|
||||
{
|
||||
return list_empty(&anchor->urb_list);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(usb_anchor_empty);
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ if USB_GADGET
|
|||
|
||||
config USB_GADGET_DEBUG
|
||||
boolean "Debugging messages (DEVELOPMENT)"
|
||||
depends on USB_GADGET && DEBUG_KERNEL
|
||||
depends on DEBUG_KERNEL
|
||||
help
|
||||
Many controller and gadget drivers will print some debugging
|
||||
messages if you use this option to ask for those messages.
|
||||
|
@ -59,7 +59,7 @@ config USB_GADGET_DEBUG
|
|||
|
||||
config USB_GADGET_DEBUG_FILES
|
||||
boolean "Debugging information files (DEVELOPMENT)"
|
||||
depends on USB_GADGET && PROC_FS
|
||||
depends on PROC_FS
|
||||
help
|
||||
Some of the drivers in the "gadget" framework can expose
|
||||
debugging information in files such as /proc/driver/udc
|
||||
|
@ -70,7 +70,7 @@ config USB_GADGET_DEBUG_FILES
|
|||
|
||||
config USB_GADGET_DEBUG_FS
|
||||
boolean "Debugging information files in debugfs (DEVELOPMENT)"
|
||||
depends on USB_GADGET && DEBUG_FS
|
||||
depends on DEBUG_FS
|
||||
help
|
||||
Some of the drivers in the "gadget" framework can expose
|
||||
debugging information in files under /sys/kernel/debug/.
|
||||
|
@ -79,12 +79,36 @@ config USB_GADGET_DEBUG_FS
|
|||
Enable these files by choosing "Y" here. If in doubt, or
|
||||
to conserve kernel memory, say "N".
|
||||
|
||||
config USB_GADGET_VBUS_DRAW
|
||||
int "Maximum VBUS Power usage (2-500 mA)"
|
||||
range 2 500
|
||||
default 2
|
||||
help
|
||||
Some devices need to draw power from USB when they are
|
||||
configured, perhaps to operate circuitry or to recharge
|
||||
batteries. This is in addition to any local power supply,
|
||||
such as an AC adapter or batteries.
|
||||
|
||||
Enter the maximum power your device draws through USB, in
|
||||
milliAmperes. The permitted range of values is 2 - 500 mA;
|
||||
0 mA would be legal, but can make some hosts misbehave.
|
||||
|
||||
This value will be used except for system-specific gadget
|
||||
drivers that have more specific information.
|
||||
|
||||
config USB_GADGET_SELECTED
|
||||
boolean
|
||||
|
||||
#
|
||||
# USB Peripheral Controller Support
|
||||
#
|
||||
# The order here is alphabetical, except that integrated controllers go
|
||||
# before discrete ones so they will be the initial/default value:
|
||||
# - integrated/SOC controllers first
|
||||
# - licensed IP used in both SOC and discrete versions
|
||||
# - discrete ones (including all PCI-only controllers)
|
||||
# - debug/dummy gadget+hcd is last.
|
||||
#
|
||||
choice
|
||||
prompt "USB Peripheral Controller"
|
||||
depends on USB_GADGET
|
||||
|
@ -94,26 +118,27 @@ choice
|
|||
Many controller drivers are platform-specific; these
|
||||
often need board-specific hooks.
|
||||
|
||||
config USB_GADGET_AMD5536UDC
|
||||
boolean "AMD5536 UDC"
|
||||
depends on PCI
|
||||
select USB_GADGET_DUALSPEED
|
||||
#
|
||||
# Integrated controllers
|
||||
#
|
||||
|
||||
config USB_GADGET_AT91
|
||||
boolean "Atmel AT91 USB Device Port"
|
||||
depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9
|
||||
select USB_GADGET_SELECTED
|
||||
help
|
||||
The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge.
|
||||
It is a USB Highspeed DMA capable USB device controller. Beside ep0
|
||||
it provides 4 IN and 4 OUT endpoints (bulk or interrupt type).
|
||||
The UDC port supports OTG operation, and may be used as a host port
|
||||
if it's not being used to implement peripheral or OTG roles.
|
||||
Many Atmel AT91 processors (such as the AT91RM2000) have a
|
||||
full speed USB Device Port with support for five configurable
|
||||
endpoints (plus endpoint zero).
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "amd5536udc" and force all
|
||||
dynamically linked module called "at91_udc" and force all
|
||||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_AMD5536UDC
|
||||
config USB_AT91
|
||||
tristate
|
||||
depends on USB_GADGET_AMD5536UDC
|
||||
depends on USB_GADGET_AT91
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_GADGET_ATMEL_USBA
|
||||
boolean "Atmel USBA"
|
||||
|
@ -150,28 +175,50 @@ config USB_FSL_USB2
|
|||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_GADGET_NET2280
|
||||
boolean "NetChip 228x"
|
||||
depends on PCI
|
||||
select USB_GADGET_DUALSPEED
|
||||
config USB_GADGET_LH7A40X
|
||||
boolean "LH7A40X"
|
||||
depends on ARCH_LH7A40X
|
||||
help
|
||||
NetChip 2280 / 2282 is a PCI based USB peripheral controller which
|
||||
supports both full and high speed USB 2.0 data transfers.
|
||||
|
||||
It has six configurable endpoints, as well as endpoint zero
|
||||
(for control transfers) and several endpoints with dedicated
|
||||
functions.
|
||||
This driver provides USB Device Controller driver for LH7A40x
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "net2280" and force all
|
||||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_NET2280
|
||||
config USB_LH7A40X
|
||||
tristate
|
||||
depends on USB_GADGET_NET2280
|
||||
depends on USB_GADGET_LH7A40X
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_GADGET_OMAP
|
||||
boolean "OMAP USB Device Controller"
|
||||
depends on ARCH_OMAP
|
||||
select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG
|
||||
help
|
||||
Many Texas Instruments OMAP processors have flexible full
|
||||
speed USB device controllers, with support for up to 30
|
||||
endpoints (plus endpoint zero). This driver supports the
|
||||
controller in the OMAP 1611, and should work with controllers
|
||||
in other OMAP processors too, given minor tweaks.
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "omap_udc" and force all
|
||||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_OMAP
|
||||
tristate
|
||||
depends on USB_GADGET_OMAP
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_OTG
|
||||
boolean "OTG Support"
|
||||
depends on USB_GADGET_OMAP && ARCH_OMAP_OTG && USB_OHCI_HCD
|
||||
help
|
||||
The most notable feature of USB OTG is support for a
|
||||
"Dual-Role" device, which can act as either a device
|
||||
or a host. The initial role choice can be changed
|
||||
later, when two dual-role devices talk to each other.
|
||||
|
||||
Select this only if your OMAP board has a Mini-AB connector.
|
||||
|
||||
config USB_GADGET_PXA25X
|
||||
boolean "PXA 25x or IXP 4xx"
|
||||
depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX
|
||||
|
@ -203,6 +250,61 @@ config USB_PXA25X_SMALL
|
|||
default y if USB_ETH
|
||||
default y if USB_G_SERIAL
|
||||
|
||||
config USB_GADGET_PXA27X
|
||||
boolean "PXA 27x"
|
||||
depends on ARCH_PXA && PXA27x
|
||||
help
|
||||
Intel's PXA 27x series XScale ARM v5TE processors include
|
||||
an integrated full speed USB 1.1 device controller.
|
||||
|
||||
It has up to 23 endpoints, as well as endpoint zero (for
|
||||
control transfers).
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "pxa27x_udc" and force all
|
||||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_PXA27X
|
||||
tristate
|
||||
depends on USB_GADGET_PXA27X
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_GADGET_S3C2410
|
||||
boolean "S3C2410 USB Device Controller"
|
||||
depends on ARCH_S3C2410
|
||||
help
|
||||
Samsung's S3C2410 is an ARM-4 processor with an integrated
|
||||
full speed USB 1.1 device controller. It has 4 configurable
|
||||
endpoints, as well as endpoint zero (for control transfers).
|
||||
|
||||
This driver has been tested on the S3C2410, S3C2412, and
|
||||
S3C2440 processors.
|
||||
|
||||
config USB_S3C2410
|
||||
tristate
|
||||
depends on USB_GADGET_S3C2410
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_S3C2410_DEBUG
|
||||
boolean "S3C2410 udc debug messages"
|
||||
depends on USB_GADGET_S3C2410
|
||||
|
||||
#
|
||||
# Controllers available in both integrated and discrete versions
|
||||
#
|
||||
|
||||
# musb builds in ../musb along with host support
|
||||
config USB_GADGET_MUSB_HDRC
|
||||
boolean "Inventra HDRC USB Peripheral (TI, ...)"
|
||||
depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
|
||||
select USB_GADGET_DUALSPEED
|
||||
select USB_GADGET_SELECTED
|
||||
help
|
||||
This OTG-capable silicon IP is used in dual designs including
|
||||
the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010.
|
||||
|
||||
config USB_GADGET_M66592
|
||||
boolean "Renesas M66592 USB Peripheral Controller"
|
||||
select USB_GADGET_DUALSPEED
|
||||
|
@ -231,23 +333,69 @@ config SUPERH_BUILT_IN_M66592
|
|||
However, this problem is improved if change a value of
|
||||
NET_IP_ALIGN to 4.
|
||||
|
||||
config USB_GADGET_PXA27X
|
||||
boolean "PXA 27x"
|
||||
depends on ARCH_PXA && PXA27x
|
||||
help
|
||||
Intel's PXA 27x series XScale ARM v5TE processors include
|
||||
an integrated full speed USB 1.1 device controller.
|
||||
#
|
||||
# Controllers available only in discrete form (and all PCI controllers)
|
||||
#
|
||||
|
||||
It has up to 23 endpoints, as well as endpoint zero (for
|
||||
control transfers).
|
||||
config USB_GADGET_AMD5536UDC
|
||||
boolean "AMD5536 UDC"
|
||||
depends on PCI
|
||||
select USB_GADGET_DUALSPEED
|
||||
help
|
||||
The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge.
|
||||
It is a USB Highspeed DMA capable USB device controller. Beside ep0
|
||||
it provides 4 IN and 4 OUT endpoints (bulk or interrupt type).
|
||||
The UDC port supports OTG operation, and may be used as a host port
|
||||
if it's not being used to implement peripheral or OTG roles.
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "pxa27x_udc" and force all
|
||||
dynamically linked module called "amd5536udc" and force all
|
||||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_PXA27X
|
||||
config USB_AMD5536UDC
|
||||
tristate
|
||||
depends on USB_GADGET_PXA27X
|
||||
depends on USB_GADGET_AMD5536UDC
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_GADGET_FSL_QE
|
||||
boolean "Freescale QE/CPM USB Device Controller"
|
||||
depends on FSL_SOC && (QUICC_ENGINE || CPM)
|
||||
help
|
||||
Some of Freescale PowerPC processors have a Full Speed
|
||||
QE/CPM2 USB controller, which support device mode with 4
|
||||
programmable endpoints. This driver supports the
|
||||
controller in the MPC8360 and MPC8272, and should work with
|
||||
controllers having QE or CPM2, given minor tweaks.
|
||||
|
||||
Set CONFIG_USB_GADGET to "m" to build this driver as a
|
||||
dynmically linked module called "fsl_qe_udc".
|
||||
|
||||
config USB_FSL_QE
|
||||
tristate
|
||||
depends on USB_GADGET_FSL_QE
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_GADGET_NET2280
|
||||
boolean "NetChip 228x"
|
||||
depends on PCI
|
||||
select USB_GADGET_DUALSPEED
|
||||
help
|
||||
NetChip 2280 / 2282 is a PCI based USB peripheral controller which
|
||||
supports both full and high speed USB 2.0 data transfers.
|
||||
|
||||
It has six configurable endpoints, as well as endpoint zero
|
||||
(for control transfers) and several endpoints with dedicated
|
||||
functions.
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "net2280" and force all
|
||||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_NET2280
|
||||
tristate
|
||||
depends on USB_GADGET_NET2280
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
|
@ -257,7 +405,7 @@ config USB_GADGET_GOKU
|
|||
help
|
||||
The Toshiba TC86C001 is a PCI device which includes controllers
|
||||
for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI).
|
||||
|
||||
|
||||
The device controller has three configurable (bulk or interrupt)
|
||||
endpoints, plus endpoint zero (for control transfers).
|
||||
|
||||
|
@ -272,98 +420,9 @@ config USB_GOKU
|
|||
select USB_GADGET_SELECTED
|
||||
|
||||
|
||||
config USB_GADGET_LH7A40X
|
||||
boolean "LH7A40X"
|
||||
depends on ARCH_LH7A40X
|
||||
help
|
||||
This driver provides USB Device Controller driver for LH7A40x
|
||||
|
||||
config USB_LH7A40X
|
||||
tristate
|
||||
depends on USB_GADGET_LH7A40X
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
# built in ../musb along with host support
|
||||
config USB_GADGET_MUSB_HDRC
|
||||
boolean "Inventra HDRC USB Peripheral (TI, ...)"
|
||||
depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
|
||||
select USB_GADGET_DUALSPEED
|
||||
select USB_GADGET_SELECTED
|
||||
help
|
||||
This OTG-capable silicon IP is used in dual designs including
|
||||
the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010.
|
||||
|
||||
config USB_GADGET_OMAP
|
||||
boolean "OMAP USB Device Controller"
|
||||
depends on ARCH_OMAP
|
||||
select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
|
||||
help
|
||||
Many Texas Instruments OMAP processors have flexible full
|
||||
speed USB device controllers, with support for up to 30
|
||||
endpoints (plus endpoint zero). This driver supports the
|
||||
controller in the OMAP 1611, and should work with controllers
|
||||
in other OMAP processors too, given minor tweaks.
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "omap_udc" and force all
|
||||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_OMAP
|
||||
tristate
|
||||
depends on USB_GADGET_OMAP
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_OTG
|
||||
boolean "OTG Support"
|
||||
depends on USB_GADGET_OMAP && ARCH_OMAP_OTG && USB_OHCI_HCD
|
||||
help
|
||||
The most notable feature of USB OTG is support for a
|
||||
"Dual-Role" device, which can act as either a device
|
||||
or a host. The initial role choice can be changed
|
||||
later, when two dual-role devices talk to each other.
|
||||
|
||||
Select this only if your OMAP board has a Mini-AB connector.
|
||||
|
||||
config USB_GADGET_S3C2410
|
||||
boolean "S3C2410 USB Device Controller"
|
||||
depends on ARCH_S3C2410
|
||||
help
|
||||
Samsung's S3C2410 is an ARM-4 processor with an integrated
|
||||
full speed USB 1.1 device controller. It has 4 configurable
|
||||
endpoints, as well as endpoint zero (for control transfers).
|
||||
|
||||
This driver has been tested on the S3C2410, S3C2412, and
|
||||
S3C2440 processors.
|
||||
|
||||
config USB_S3C2410
|
||||
tristate
|
||||
depends on USB_GADGET_S3C2410
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_S3C2410_DEBUG
|
||||
boolean "S3C2410 udc debug messages"
|
||||
depends on USB_GADGET_S3C2410
|
||||
|
||||
config USB_GADGET_AT91
|
||||
boolean "AT91 USB Device Port"
|
||||
depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9
|
||||
select USB_GADGET_SELECTED
|
||||
help
|
||||
Many Atmel AT91 processors (such as the AT91RM2000) have a
|
||||
full speed USB Device Port with support for five configurable
|
||||
endpoints (plus endpoint zero).
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "at91_udc" and force all
|
||||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_AT91
|
||||
tristate
|
||||
depends on USB_GADGET_AT91
|
||||
default USB_GADGET
|
||||
#
|
||||
# LAST -- dummy/emulated controller
|
||||
#
|
||||
|
||||
config USB_GADGET_DUMMY_HCD
|
||||
boolean "Dummy HCD (DEVELOPMENT)"
|
||||
|
@ -553,19 +612,23 @@ config USB_FILE_STORAGE_TEST
|
|||
normal operation.
|
||||
|
||||
config USB_G_SERIAL
|
||||
tristate "Serial Gadget (with CDC ACM support)"
|
||||
tristate "Serial Gadget (with CDC ACM and CDC OBEX support)"
|
||||
help
|
||||
The Serial Gadget talks to the Linux-USB generic serial driver.
|
||||
This driver supports a CDC-ACM module option, which can be used
|
||||
to interoperate with MS-Windows hosts or with the Linux-USB
|
||||
"cdc-acm" driver.
|
||||
|
||||
This driver also supports a CDC-OBEX option. You will need a
|
||||
user space OBEX server talking to /dev/ttyGS*, since the kernel
|
||||
itself doesn't implement the OBEX protocol.
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "g_serial".
|
||||
|
||||
For more information, see Documentation/usb/gadget_serial.txt
|
||||
which includes instructions and a "driver info file" needed to
|
||||
make MS-Windows work with this driver.
|
||||
make MS-Windows work with CDC ACM.
|
||||
|
||||
config USB_MIDI_GADGET
|
||||
tristate "MIDI Gadget (EXPERIMENTAL)"
|
||||
|
|
|
@ -18,6 +18,7 @@ obj-$(CONFIG_USB_AT91) += at91_udc.o
|
|||
obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o
|
||||
obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o
|
||||
obj-$(CONFIG_USB_M66592) += m66592-udc.o
|
||||
obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o
|
||||
|
||||
#
|
||||
# USB gadget drivers
|
||||
|
|
|
@ -155,7 +155,6 @@ static struct usb_configuration cdc_config_driver = {
|
|||
.bConfigurationValue = 1,
|
||||
/* .iConfiguration = DYNAMIC */
|
||||
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
|
||||
.bMaxPower = 1, /* 2 mA, minimal */
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
|
|
@ -127,6 +127,70 @@ done:
|
|||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_function_deactivate - prevent function and gadget enumeration
|
||||
* @function: the function that isn't yet ready to respond
|
||||
*
|
||||
* Blocks response of the gadget driver to host enumeration by
|
||||
* preventing the data line pullup from being activated. This is
|
||||
* normally called during @bind() processing to change from the
|
||||
* initial "ready to respond" state, or when a required resource
|
||||
* becomes available.
|
||||
*
|
||||
* For example, drivers that serve as a passthrough to a userspace
|
||||
* daemon can block enumeration unless that daemon (such as an OBEX,
|
||||
* MTP, or print server) is ready to handle host requests.
|
||||
*
|
||||
* Not all systems support software control of their USB peripheral
|
||||
* data pullups.
|
||||
*
|
||||
* Returns zero on success, else negative errno.
|
||||
*/
|
||||
int usb_function_deactivate(struct usb_function *function)
|
||||
{
|
||||
struct usb_composite_dev *cdev = function->config->cdev;
|
||||
int status = 0;
|
||||
|
||||
spin_lock(&cdev->lock);
|
||||
|
||||
if (cdev->deactivations == 0)
|
||||
status = usb_gadget_disconnect(cdev->gadget);
|
||||
if (status == 0)
|
||||
cdev->deactivations++;
|
||||
|
||||
spin_unlock(&cdev->lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_function_activate - allow function and gadget enumeration
|
||||
* @function: function on which usb_function_activate() was called
|
||||
*
|
||||
* Reverses effect of usb_function_deactivate(). If no more functions
|
||||
* are delaying their activation, the gadget driver will respond to
|
||||
* host enumeration procedures.
|
||||
*
|
||||
* Returns zero on success, else negative errno.
|
||||
*/
|
||||
int usb_function_activate(struct usb_function *function)
|
||||
{
|
||||
struct usb_composite_dev *cdev = function->config->cdev;
|
||||
int status = 0;
|
||||
|
||||
spin_lock(&cdev->lock);
|
||||
|
||||
if (WARN_ON(cdev->deactivations == 0))
|
||||
status = -EINVAL;
|
||||
else {
|
||||
cdev->deactivations--;
|
||||
if (cdev->deactivations == 0)
|
||||
status = usb_gadget_connect(cdev->gadget);
|
||||
}
|
||||
|
||||
spin_unlock(&cdev->lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_interface_id() - allocate an unused interface ID
|
||||
* @config: configuration associated with the interface
|
||||
|
@ -181,7 +245,7 @@ static int config_buf(struct usb_configuration *config,
|
|||
c->bConfigurationValue = config->bConfigurationValue;
|
||||
c->iConfiguration = config->iConfiguration;
|
||||
c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
|
||||
c->bMaxPower = config->bMaxPower;
|
||||
c->bMaxPower = config->bMaxPower ? : (CONFIG_USB_GADGET_VBUS_DRAW / 2);
|
||||
|
||||
/* There may be e.g. OTG descriptors */
|
||||
if (config->descriptors) {
|
||||
|
@ -368,7 +432,7 @@ static int set_config(struct usb_composite_dev *cdev,
|
|||
}
|
||||
|
||||
/* when we return, be sure our power usage is valid */
|
||||
power = 2 * c->bMaxPower;
|
||||
power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW;
|
||||
done:
|
||||
usb_gadget_vbus_draw(gadget, power);
|
||||
return result;
|
||||
|
|
|
@ -82,6 +82,7 @@ struct dummy_ep {
|
|||
const struct usb_endpoint_descriptor *desc;
|
||||
struct usb_ep ep;
|
||||
unsigned halted : 1;
|
||||
unsigned wedged : 1;
|
||||
unsigned already_seen : 1;
|
||||
unsigned setup_stage : 1;
|
||||
};
|
||||
|
@ -436,6 +437,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
|||
/* at this point real hardware should be NAKing transfers
|
||||
* to that endpoint, until a buffer is queued to it.
|
||||
*/
|
||||
ep->halted = ep->wedged = 0;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
|
@ -597,7 +599,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
|
|||
}
|
||||
|
||||
static int
|
||||
dummy_set_halt (struct usb_ep *_ep, int value)
|
||||
dummy_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
|
||||
{
|
||||
struct dummy_ep *ep;
|
||||
struct dummy *dum;
|
||||
|
@ -609,16 +611,32 @@ dummy_set_halt (struct usb_ep *_ep, int value)
|
|||
if (!dum->driver)
|
||||
return -ESHUTDOWN;
|
||||
if (!value)
|
||||
ep->halted = 0;
|
||||
ep->halted = ep->wedged = 0;
|
||||
else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) &&
|
||||
!list_empty (&ep->queue))
|
||||
return -EAGAIN;
|
||||
else
|
||||
else {
|
||||
ep->halted = 1;
|
||||
if (wedged)
|
||||
ep->wedged = 1;
|
||||
}
|
||||
/* FIXME clear emulated data toggle too */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dummy_set_halt(struct usb_ep *_ep, int value)
|
||||
{
|
||||
return dummy_set_halt_and_wedge(_ep, value, 0);
|
||||
}
|
||||
|
||||
static int dummy_set_wedge(struct usb_ep *_ep)
|
||||
{
|
||||
if (!_ep || _ep->name == ep0name)
|
||||
return -EINVAL;
|
||||
return dummy_set_halt_and_wedge(_ep, 1, 1);
|
||||
}
|
||||
|
||||
static const struct usb_ep_ops dummy_ep_ops = {
|
||||
.enable = dummy_enable,
|
||||
.disable = dummy_disable,
|
||||
|
@ -630,6 +648,7 @@ static const struct usb_ep_ops dummy_ep_ops = {
|
|||
.dequeue = dummy_dequeue,
|
||||
|
||||
.set_halt = dummy_set_halt,
|
||||
.set_wedge = dummy_set_wedge,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -760,7 +779,8 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
|
|||
ep->ep.name = ep_name [i];
|
||||
ep->ep.ops = &dummy_ep_ops;
|
||||
list_add_tail (&ep->ep.ep_list, &dum->gadget.ep_list);
|
||||
ep->halted = ep->already_seen = ep->setup_stage = 0;
|
||||
ep->halted = ep->wedged = ep->already_seen =
|
||||
ep->setup_stage = 0;
|
||||
ep->ep.maxpacket = ~0;
|
||||
ep->last_io = jiffies;
|
||||
ep->gadget = &dum->gadget;
|
||||
|
@ -1351,7 +1371,7 @@ restart:
|
|||
} else if (setup.bRequestType == Ep_Request) {
|
||||
// endpoint halt
|
||||
ep2 = find_endpoint (dum, w_index);
|
||||
if (!ep2) {
|
||||
if (!ep2 || ep2->ep.name == ep0name) {
|
||||
value = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
@ -1380,7 +1400,8 @@ restart:
|
|||
value = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
ep2->halted = 0;
|
||||
if (!ep2->wedged)
|
||||
ep2->halted = 0;
|
||||
value = 0;
|
||||
status = 0;
|
||||
}
|
||||
|
|
|
@ -242,7 +242,6 @@ static struct usb_configuration rndis_config_driver = {
|
|||
.bConfigurationValue = 2,
|
||||
/* .iConfiguration = DYNAMIC */
|
||||
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
|
||||
.bMaxPower = 1, /* 2 mA, minimal */
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -271,7 +270,6 @@ static struct usb_configuration eth_config_driver = {
|
|||
.bConfigurationValue = 1,
|
||||
/* .iConfiguration = DYNAMIC */
|
||||
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
|
||||
.bMaxPower = 1, /* 2 mA, minimal */
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
|
|
@ -352,7 +352,6 @@ static struct usb_configuration loopback_driver = {
|
|||
.bind = loopback_bind_config,
|
||||
.bConfigurationValue = 2,
|
||||
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
|
||||
.bMaxPower = 1, /* 2 mA, minimal */
|
||||
/* .iConfiguration = DYNAMIC */
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,493 @@
|
|||
/*
|
||||
* f_obex.c -- USB CDC OBEX function driver
|
||||
*
|
||||
* Copyright (C) 2008 Nokia Corporation
|
||||
* Contact: Felipe Balbi <felipe.balbi@nokia.com>
|
||||
*
|
||||
* Based on f_acm.c by Al Borchers and 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
|
||||
*/
|
||||
|
||||
/* #define VERBOSE_DEBUG */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "u_serial.h"
|
||||
#include "gadget_chips.h"
|
||||
|
||||
|
||||
/*
|
||||
* This CDC OBEX function support just packages a TTY-ish byte stream.
|
||||
* A user mode server will put it into "raw" mode and handle all the
|
||||
* relevant protocol details ... this is just a kernel passthrough.
|
||||
* When possible, we prevent gadget enumeration until that server is
|
||||
* ready to handle the commands.
|
||||
*/
|
||||
|
||||
struct obex_ep_descs {
|
||||
struct usb_endpoint_descriptor *obex_in;
|
||||
struct usb_endpoint_descriptor *obex_out;
|
||||
};
|
||||
|
||||
struct f_obex {
|
||||
struct gserial port;
|
||||
u8 ctrl_id;
|
||||
u8 data_id;
|
||||
u8 port_num;
|
||||
u8 can_activate;
|
||||
|
||||
struct obex_ep_descs fs;
|
||||
struct obex_ep_descs hs;
|
||||
};
|
||||
|
||||
static inline struct f_obex *func_to_obex(struct usb_function *f)
|
||||
{
|
||||
return container_of(f, struct f_obex, port.func);
|
||||
}
|
||||
|
||||
static inline struct f_obex *port_to_obex(struct gserial *p)
|
||||
{
|
||||
return container_of(p, struct f_obex, port);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#define OBEX_CTRL_IDX 0
|
||||
#define OBEX_DATA_IDX 1
|
||||
|
||||
static struct usb_string obex_string_defs[] = {
|
||||
[OBEX_CTRL_IDX].s = "CDC Object Exchange (OBEX)",
|
||||
[OBEX_DATA_IDX].s = "CDC OBEX Data",
|
||||
{ }, /* end of list */
|
||||
};
|
||||
|
||||
static struct usb_gadget_strings obex_string_table = {
|
||||
.language = 0x0409, /* en-US */
|
||||
.strings = obex_string_defs,
|
||||
};
|
||||
|
||||
static struct usb_gadget_strings *obex_strings[] = {
|
||||
&obex_string_table,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct usb_interface_descriptor obex_control_intf __initdata = {
|
||||
.bLength = sizeof(obex_control_intf),
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 0,
|
||||
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 0,
|
||||
.bInterfaceClass = USB_CLASS_COMM,
|
||||
.bInterfaceSubClass = USB_CDC_SUBCLASS_OBEX,
|
||||
};
|
||||
|
||||
static struct usb_interface_descriptor obex_data_nop_intf __initdata = {
|
||||
.bLength = sizeof(obex_data_nop_intf),
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 1,
|
||||
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 0,
|
||||
.bInterfaceClass = USB_CLASS_CDC_DATA,
|
||||
};
|
||||
|
||||
static struct usb_interface_descriptor obex_data_intf __initdata = {
|
||||
.bLength = sizeof(obex_data_intf),
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 2,
|
||||
|
||||
.bAlternateSetting = 1,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = USB_CLASS_CDC_DATA,
|
||||
};
|
||||
|
||||
static struct usb_cdc_header_desc obex_cdc_header_desc __initdata = {
|
||||
.bLength = sizeof(obex_cdc_header_desc),
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
|
||||
.bcdCDC = __constant_cpu_to_le16(0x0120),
|
||||
};
|
||||
|
||||
static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = {
|
||||
.bLength = sizeof(obex_cdc_union_desc),
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_UNION_TYPE,
|
||||
.bMasterInterface0 = 1,
|
||||
.bSlaveInterface0 = 2,
|
||||
};
|
||||
|
||||
static struct usb_cdc_obex_desc obex_desc __initdata = {
|
||||
.bLength = sizeof(obex_desc),
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_OBEX_TYPE,
|
||||
.bcdVersion = __constant_cpu_to_le16(0x0100),
|
||||
};
|
||||
|
||||
/* High-Speed Support */
|
||||
|
||||
static struct usb_endpoint_descriptor obex_hs_ep_out_desc __initdata = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *hs_function[] __initdata = {
|
||||
(struct usb_descriptor_header *) &obex_control_intf,
|
||||
(struct usb_descriptor_header *) &obex_cdc_header_desc,
|
||||
(struct usb_descriptor_header *) &obex_desc,
|
||||
(struct usb_descriptor_header *) &obex_cdc_union_desc,
|
||||
|
||||
(struct usb_descriptor_header *) &obex_data_nop_intf,
|
||||
(struct usb_descriptor_header *) &obex_data_intf,
|
||||
(struct usb_descriptor_header *) &obex_hs_ep_in_desc,
|
||||
(struct usb_descriptor_header *) &obex_hs_ep_out_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Full-Speed Support */
|
||||
|
||||
static struct usb_endpoint_descriptor obex_fs_ep_in_desc __initdata = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor obex_fs_ep_out_desc __initdata = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *fs_function[] __initdata = {
|
||||
(struct usb_descriptor_header *) &obex_control_intf,
|
||||
(struct usb_descriptor_header *) &obex_cdc_header_desc,
|
||||
(struct usb_descriptor_header *) &obex_desc,
|
||||
(struct usb_descriptor_header *) &obex_cdc_union_desc,
|
||||
|
||||
(struct usb_descriptor_header *) &obex_data_nop_intf,
|
||||
(struct usb_descriptor_header *) &obex_data_intf,
|
||||
(struct usb_descriptor_header *) &obex_fs_ep_in_desc,
|
||||
(struct usb_descriptor_header *) &obex_fs_ep_out_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
||||
{
|
||||
struct f_obex *obex = func_to_obex(f);
|
||||
struct usb_composite_dev *cdev = f->config->cdev;
|
||||
|
||||
if (intf == obex->ctrl_id) {
|
||||
if (alt != 0)
|
||||
goto fail;
|
||||
/* NOP */
|
||||
DBG(cdev, "reset obex ttyGS%d control\n", obex->port_num);
|
||||
|
||||
} else if (intf == obex->data_id) {
|
||||
if (alt > 1)
|
||||
goto fail;
|
||||
|
||||
if (obex->port.in->driver_data) {
|
||||
DBG(cdev, "reset obex ttyGS%d\n", obex->port_num);
|
||||
gserial_disconnect(&obex->port);
|
||||
}
|
||||
|
||||
if (!obex->port.in_desc) {
|
||||
DBG(cdev, "init obex ttyGS%d\n", obex->port_num);
|
||||
obex->port.in_desc = ep_choose(cdev->gadget,
|
||||
obex->hs.obex_in, obex->fs.obex_in);
|
||||
obex->port.out_desc = ep_choose(cdev->gadget,
|
||||
obex->hs.obex_out, obex->fs.obex_out);
|
||||
}
|
||||
|
||||
if (alt == 1) {
|
||||
DBG(cdev, "activate obex ttyGS%d\n", obex->port_num);
|
||||
gserial_connect(&obex->port, obex->port_num);
|
||||
}
|
||||
|
||||
} else
|
||||
goto fail;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int obex_get_alt(struct usb_function *f, unsigned intf)
|
||||
{
|
||||
struct f_obex *obex = func_to_obex(f);
|
||||
|
||||
if (intf == obex->ctrl_id)
|
||||
return 0;
|
||||
|
||||
return obex->port.in->driver_data ? 1 : 0;
|
||||
}
|
||||
|
||||
static void obex_disable(struct usb_function *f)
|
||||
{
|
||||
struct f_obex *obex = func_to_obex(f);
|
||||
struct usb_composite_dev *cdev = f->config->cdev;
|
||||
|
||||
DBG(cdev, "obex ttyGS%d disable\n", obex->port_num);
|
||||
gserial_disconnect(&obex->port);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static void obex_connect(struct gserial *g)
|
||||
{
|
||||
struct f_obex *obex = port_to_obex(g);
|
||||
struct usb_composite_dev *cdev = g->func.config->cdev;
|
||||
int status;
|
||||
|
||||
if (!obex->can_activate)
|
||||
return;
|
||||
|
||||
status = usb_function_activate(&g->func);
|
||||
if (status)
|
||||
DBG(cdev, "obex ttyGS%d function activate --> %d\n",
|
||||
obex->port_num, status);
|
||||
}
|
||||
|
||||
static void obex_disconnect(struct gserial *g)
|
||||
{
|
||||
struct f_obex *obex = port_to_obex(g);
|
||||
struct usb_composite_dev *cdev = g->func.config->cdev;
|
||||
int status;
|
||||
|
||||
if (!obex->can_activate)
|
||||
return;
|
||||
|
||||
status = usb_function_deactivate(&g->func);
|
||||
if (status)
|
||||
DBG(cdev, "obex ttyGS%d function deactivate --> %d\n",
|
||||
obex->port_num, status);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init
|
||||
obex_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
struct usb_composite_dev *cdev = c->cdev;
|
||||
struct f_obex *obex = func_to_obex(f);
|
||||
int status;
|
||||
struct usb_ep *ep;
|
||||
|
||||
/* allocate instance-specific interface IDs, and patch descriptors */
|
||||
|
||||
status = usb_interface_id(c, f);
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
obex->ctrl_id = status;
|
||||
|
||||
obex_control_intf.bInterfaceNumber = status;
|
||||
obex_cdc_union_desc.bMasterInterface0 = status;
|
||||
|
||||
status = usb_interface_id(c, f);
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
obex->data_id = status;
|
||||
|
||||
obex_data_nop_intf.bInterfaceNumber = status;
|
||||
obex_data_intf.bInterfaceNumber = status;
|
||||
obex_cdc_union_desc.bSlaveInterface0 = status;
|
||||
|
||||
/* allocate instance-specific endpoints */
|
||||
|
||||
ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_in_desc);
|
||||
if (!ep)
|
||||
goto fail;
|
||||
obex->port.in = ep;
|
||||
ep->driver_data = cdev; /* claim */
|
||||
|
||||
ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_out_desc);
|
||||
if (!ep)
|
||||
goto fail;
|
||||
obex->port.out = ep;
|
||||
ep->driver_data = cdev; /* claim */
|
||||
|
||||
/* copy descriptors, and track endpoint copies */
|
||||
f->descriptors = usb_copy_descriptors(fs_function);
|
||||
|
||||
obex->fs.obex_in = usb_find_endpoint(fs_function,
|
||||
f->descriptors, &obex_fs_ep_in_desc);
|
||||
obex->fs.obex_out = usb_find_endpoint(fs_function,
|
||||
f->descriptors, &obex_fs_ep_out_desc);
|
||||
|
||||
/* support all relevant hardware speeds... we expect that when
|
||||
* hardware is dual speed, all bulk-capable endpoints work at
|
||||
* both speeds
|
||||
*/
|
||||
if (gadget_is_dualspeed(c->cdev->gadget)) {
|
||||
|
||||
obex_hs_ep_in_desc.bEndpointAddress =
|
||||
obex_fs_ep_in_desc.bEndpointAddress;
|
||||
obex_hs_ep_out_desc.bEndpointAddress =
|
||||
obex_fs_ep_out_desc.bEndpointAddress;
|
||||
|
||||
/* copy descriptors, and track endpoint copies */
|
||||
f->hs_descriptors = usb_copy_descriptors(hs_function);
|
||||
|
||||
obex->hs.obex_in = usb_find_endpoint(hs_function,
|
||||
f->descriptors, &obex_hs_ep_in_desc);
|
||||
obex->hs.obex_out = usb_find_endpoint(hs_function,
|
||||
f->descriptors, &obex_hs_ep_out_desc);
|
||||
}
|
||||
|
||||
/* Avoid letting this gadget enumerate until the userspace
|
||||
* OBEX server is active.
|
||||
*/
|
||||
status = usb_function_deactivate(f);
|
||||
if (status < 0)
|
||||
WARNING(cdev, "obex ttyGS%d: can't prevent enumeration, %d\n",
|
||||
obex->port_num, status);
|
||||
else
|
||||
obex->can_activate = true;
|
||||
|
||||
|
||||
DBG(cdev, "obex ttyGS%d: %s speed IN/%s OUT/%s\n",
|
||||
obex->port_num,
|
||||
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
|
||||
obex->port.in->name, obex->port.out->name);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
/* we might as well release our claims on endpoints */
|
||||
if (obex->port.out)
|
||||
obex->port.out->driver_data = NULL;
|
||||
if (obex->port.in)
|
||||
obex->port.in->driver_data = NULL;
|
||||
|
||||
ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
obex_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
if (gadget_is_dualspeed(c->cdev->gadget))
|
||||
usb_free_descriptors(f->hs_descriptors);
|
||||
usb_free_descriptors(f->descriptors);
|
||||
kfree(func_to_obex(f));
|
||||
}
|
||||
|
||||
/* Some controllers can't support CDC OBEX ... */
|
||||
static inline bool can_support_obex(struct usb_configuration *c)
|
||||
{
|
||||
/* Since the first interface is a NOP, we can ignore the
|
||||
* issue of multi-interface support on most controllers.
|
||||
*
|
||||
* Altsettings are mandatory, however...
|
||||
*/
|
||||
if (!gadget_supports_altsettings(c->cdev->gadget))
|
||||
return false;
|
||||
|
||||
/* everything else is *probably* fine ... */
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* obex_bind_config - add a CDC OBEX function to a configuration
|
||||
* @c: the configuration to support the CDC OBEX instance
|
||||
* @port_num: /dev/ttyGS* port this interface will use
|
||||
* Context: single threaded during gadget setup
|
||||
*
|
||||
* Returns zero on success, else negative errno.
|
||||
*
|
||||
* Caller must have called @gserial_setup() with enough ports to
|
||||
* handle all the ones it binds. Caller is also responsible
|
||||
* for calling @gserial_cleanup() before module unload.
|
||||
*/
|
||||
int __init obex_bind_config(struct usb_configuration *c, u8 port_num)
|
||||
{
|
||||
struct f_obex *obex;
|
||||
int status;
|
||||
|
||||
if (!can_support_obex(c))
|
||||
return -EINVAL;
|
||||
|
||||
/* maybe allocate device-global string IDs, and patch descriptors */
|
||||
if (obex_string_defs[OBEX_CTRL_IDX].id == 0) {
|
||||
status = usb_string_id(c->cdev);
|
||||
if (status < 0)
|
||||
return status;
|
||||
obex_string_defs[OBEX_CTRL_IDX].id = status;
|
||||
|
||||
obex_control_intf.iInterface = status;
|
||||
|
||||
status = usb_string_id(c->cdev);
|
||||
if (status < 0)
|
||||
return status;
|
||||
obex_string_defs[OBEX_DATA_IDX].id = status;
|
||||
|
||||
obex_data_nop_intf.iInterface =
|
||||
obex_data_intf.iInterface = status;
|
||||
}
|
||||
|
||||
/* allocate and initialize one new instance */
|
||||
obex = kzalloc(sizeof *obex, GFP_KERNEL);
|
||||
if (!obex)
|
||||
return -ENOMEM;
|
||||
|
||||
obex->port_num = port_num;
|
||||
|
||||
obex->port.connect = obex_connect;
|
||||
obex->port.disconnect = obex_disconnect;
|
||||
|
||||
obex->port.func.name = "obex";
|
||||
obex->port.func.strings = obex_strings;
|
||||
/* descriptors are per-instance copies */
|
||||
obex->port.func.bind = obex_bind;
|
||||
obex->port.func.unbind = obex_unbind;
|
||||
obex->port.func.set_alt = obex_set_alt;
|
||||
obex->port.func.get_alt = obex_get_alt;
|
||||
obex->port.func.disable = obex_disable;
|
||||
|
||||
status = usb_add_function(c, &obex->port.func);
|
||||
if (status)
|
||||
kfree(obex);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Felipe Balbi");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -552,7 +552,6 @@ static struct usb_configuration sourcesink_driver = {
|
|||
.setup = sourcesink_setup,
|
||||
.bConfigurationValue = 3,
|
||||
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
|
||||
.bMaxPower = 1, /* 2 mA, minimal */
|
||||
/* .iConfiguration = DYNAMIC */
|
||||
};
|
||||
|
||||
|
|
|
@ -851,7 +851,7 @@ config_desc = {
|
|||
.bConfigurationValue = CONFIG_VALUE,
|
||||
.iConfiguration = STRING_CONFIG,
|
||||
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
||||
.bMaxPower = 1, // self-powered
|
||||
.bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2,
|
||||
};
|
||||
|
||||
static struct usb_otg_descriptor
|
||||
|
@ -2676,11 +2676,24 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
|
|||
/* Verify the length of the command itself */
|
||||
if (cmnd_size != fsg->cmnd_size) {
|
||||
|
||||
/* Special case workaround: MS-Windows issues REQUEST SENSE
|
||||
* with cbw->Length == 12 (it should be 6). */
|
||||
if (fsg->cmnd[0] == SC_REQUEST_SENSE && fsg->cmnd_size == 12)
|
||||
/* Special case workaround: There are plenty of buggy SCSI
|
||||
* implementations. Many have issues with cbw->Length
|
||||
* field passing a wrong command size. For those cases we
|
||||
* always try to work around the problem by using the length
|
||||
* sent by the host side provided it is at least as large
|
||||
* as the correct command length.
|
||||
* Examples of such cases would be MS-Windows, which issues
|
||||
* REQUEST SENSE with cbw->Length == 12 where it should
|
||||
* be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and
|
||||
* REQUEST SENSE with cbw->Length == 10 where it should
|
||||
* be 6 as well.
|
||||
*/
|
||||
if (cmnd_size <= fsg->cmnd_size) {
|
||||
DBG(fsg, "%s is buggy! Expected length %d "
|
||||
"but we got %d\n", name,
|
||||
cmnd_size, fsg->cmnd_size);
|
||||
cmnd_size = fsg->cmnd_size;
|
||||
else {
|
||||
} else {
|
||||
fsg->phase_error = 1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* drivers/usb/gadget/qe_udc.h
|
||||
*
|
||||
* Copyright (C) 2006-2008 Freescale Semiconductor, Inc. All rights reserved.
|
||||
*
|
||||
* Xiaobo Xie <X.Xie@freescale.com>
|
||||
* Li Yang <leoli@freescale.com>
|
||||
*
|
||||
* Description:
|
||||
* Freescale USB device/endpoint management registers
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __FSL_QE_UDC_H
|
||||
#define __FSL_QE_UDC_H
|
||||
|
||||
/* SoC type */
|
||||
#define PORT_CPM 0
|
||||
#define PORT_QE 1
|
||||
|
||||
#define USB_MAX_ENDPOINTS 4
|
||||
#define USB_MAX_PIPES USB_MAX_ENDPOINTS
|
||||
#define USB_EP0_MAX_SIZE 64
|
||||
#define USB_MAX_CTRL_PAYLOAD 0x4000
|
||||
#define USB_BDRING_LEN 16
|
||||
#define USB_BDRING_LEN_RX 256
|
||||
#define USB_BDRING_LEN_TX 16
|
||||
#define MIN_EMPTY_BDS 128
|
||||
#define MAX_DATA_BDS 8
|
||||
#define USB_CRC_SIZE 2
|
||||
#define USB_DIR_BOTH 0x88
|
||||
#define R_BUF_MAXSIZE 0x800
|
||||
#define USB_EP_PARA_ALIGNMENT 32
|
||||
|
||||
/* USB Mode Register bit define */
|
||||
#define USB_MODE_EN 0x01
|
||||
#define USB_MODE_HOST 0x02
|
||||
#define USB_MODE_TEST 0x04
|
||||
#define USB_MODE_SFTE 0x08
|
||||
#define USB_MODE_RESUME 0x40
|
||||
#define USB_MODE_LSS 0x80
|
||||
|
||||
/* USB Slave Address Register Mask */
|
||||
#define USB_SLVADDR_MASK 0x7F
|
||||
|
||||
/* USB Endpoint register define */
|
||||
#define USB_EPNUM_MASK 0xF000
|
||||
#define USB_EPNUM_SHIFT 12
|
||||
|
||||
#define USB_TRANS_MODE_SHIFT 8
|
||||
#define USB_TRANS_CTR 0x0000
|
||||
#define USB_TRANS_INT 0x0100
|
||||
#define USB_TRANS_BULK 0x0200
|
||||
#define USB_TRANS_ISO 0x0300
|
||||
|
||||
#define USB_EP_MF 0x0020
|
||||
#define USB_EP_RTE 0x0010
|
||||
|
||||
#define USB_THS_SHIFT 2
|
||||
#define USB_THS_MASK 0x000c
|
||||
#define USB_THS_NORMAL 0x0
|
||||
#define USB_THS_IGNORE_IN 0x0004
|
||||
#define USB_THS_NACK 0x0008
|
||||
#define USB_THS_STALL 0x000c
|
||||
|
||||
#define USB_RHS_SHIFT 0
|
||||
#define USB_RHS_MASK 0x0003
|
||||
#define USB_RHS_NORMAL 0x0
|
||||
#define USB_RHS_IGNORE_OUT 0x0001
|
||||
#define USB_RHS_NACK 0x0002
|
||||
#define USB_RHS_STALL 0x0003
|
||||
|
||||
#define USB_RTHS_MASK 0x000f
|
||||
|
||||
/* USB Command Register define */
|
||||
#define USB_CMD_STR_FIFO 0x80
|
||||
#define USB_CMD_FLUSH_FIFO 0x40
|
||||
#define USB_CMD_ISFT 0x20
|
||||
#define USB_CMD_DSFT 0x10
|
||||
#define USB_CMD_EP_MASK 0x03
|
||||
|
||||
/* USB Event and Mask Register define */
|
||||
#define USB_E_MSF_MASK 0x0800
|
||||
#define USB_E_SFT_MASK 0x0400
|
||||
#define USB_E_RESET_MASK 0x0200
|
||||
#define USB_E_IDLE_MASK 0x0100
|
||||
#define USB_E_TXE4_MASK 0x0080
|
||||
#define USB_E_TXE3_MASK 0x0040
|
||||
#define USB_E_TXE2_MASK 0x0020
|
||||
#define USB_E_TXE1_MASK 0x0010
|
||||
#define USB_E_SOF_MASK 0x0008
|
||||
#define USB_E_BSY_MASK 0x0004
|
||||
#define USB_E_TXB_MASK 0x0002
|
||||
#define USB_E_RXB_MASK 0x0001
|
||||
#define USBER_ALL_CLEAR 0x0fff
|
||||
|
||||
#define USB_E_DEFAULT_DEVICE (USB_E_RESET_MASK | USB_E_TXE4_MASK | \
|
||||
USB_E_TXE3_MASK | USB_E_TXE2_MASK | \
|
||||
USB_E_TXE1_MASK | USB_E_BSY_MASK | \
|
||||
USB_E_TXB_MASK | USB_E_RXB_MASK)
|
||||
|
||||
#define USB_E_TXE_MASK (USB_E_TXE4_MASK | USB_E_TXE3_MASK|\
|
||||
USB_E_TXE2_MASK | USB_E_TXE1_MASK)
|
||||
/* USB Status Register define */
|
||||
#define USB_IDLE_STATUS_MASK 0x01
|
||||
|
||||
/* USB Start of Frame Timer */
|
||||
#define USB_USSFT_MASK 0x3FFF
|
||||
|
||||
/* USB Frame Number Register */
|
||||
#define USB_USFRN_MASK 0xFFFF
|
||||
|
||||
struct usb_device_para{
|
||||
u16 epptr[4];
|
||||
u32 rstate;
|
||||
u32 rptr;
|
||||
u16 frame_n;
|
||||
u16 rbcnt;
|
||||
u32 rtemp;
|
||||
u32 rxusb_data;
|
||||
u16 rxuptr;
|
||||
u8 reso[2];
|
||||
u32 softbl;
|
||||
u8 sofucrctemp;
|
||||
};
|
||||
|
||||
struct usb_ep_para{
|
||||
u16 rbase;
|
||||
u16 tbase;
|
||||
u8 rbmr;
|
||||
u8 tbmr;
|
||||
u16 mrblr;
|
||||
u16 rbptr;
|
||||
u16 tbptr;
|
||||
u32 tstate;
|
||||
u32 tptr;
|
||||
u16 tcrc;
|
||||
u16 tbcnt;
|
||||
u32 ttemp;
|
||||
u16 txusbu_ptr;
|
||||
u8 reserve[2];
|
||||
};
|
||||
|
||||
#define USB_BUSMODE_GBL 0x20
|
||||
#define USB_BUSMODE_BO_MASK 0x18
|
||||
#define USB_BUSMODE_BO_SHIFT 0x3
|
||||
#define USB_BUSMODE_BE 0x2
|
||||
#define USB_BUSMODE_CETM 0x04
|
||||
#define USB_BUSMODE_DTB 0x02
|
||||
|
||||
/* Endpoint basic handle */
|
||||
#define ep_index(EP) ((EP)->desc->bEndpointAddress & 0xF)
|
||||
#define ep_maxpacket(EP) ((EP)->ep.maxpacket)
|
||||
#define ep_is_in(EP) ((ep_index(EP) == 0) ? (EP->udc->ep0_dir == \
|
||||
USB_DIR_IN) : ((EP)->desc->bEndpointAddress \
|
||||
& USB_DIR_IN) == USB_DIR_IN)
|
||||
|
||||
/* ep0 transfer state */
|
||||
#define WAIT_FOR_SETUP 0
|
||||
#define DATA_STATE_XMIT 1
|
||||
#define DATA_STATE_NEED_ZLP 2
|
||||
#define WAIT_FOR_OUT_STATUS 3
|
||||
#define DATA_STATE_RECV 4
|
||||
|
||||
/* ep tramsfer mode */
|
||||
#define USBP_TM_CTL 0
|
||||
#define USBP_TM_ISO 1
|
||||
#define USBP_TM_BULK 2
|
||||
#define USBP_TM_INT 3
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
USB RX And TX DATA Frame
|
||||
-----------------------------------------------------------------------------*/
|
||||
struct qe_frame{
|
||||
u8 *data;
|
||||
u32 len;
|
||||
u32 status;
|
||||
u32 info;
|
||||
|
||||
void *privdata;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
/* Frame structure, info field. */
|
||||
#define PID_DATA0 0x80000000 /* Data toggle zero */
|
||||
#define PID_DATA1 0x40000000 /* Data toggle one */
|
||||
#define PID_SETUP 0x20000000 /* setup bit */
|
||||
#define SETUP_STATUS 0x10000000 /* setup status bit */
|
||||
#define SETADDR_STATUS 0x08000000 /* setupup address status bit */
|
||||
#define NO_REQ 0x04000000 /* Frame without request */
|
||||
#define HOST_DATA 0x02000000 /* Host data frame */
|
||||
#define FIRST_PACKET_IN_FRAME 0x01000000 /* first packet in the frame */
|
||||
#define TOKEN_FRAME 0x00800000 /* Host token frame */
|
||||
#define ZLP 0x00400000 /* Zero length packet */
|
||||
#define IN_TOKEN_FRAME 0x00200000 /* In token package */
|
||||
#define OUT_TOKEN_FRAME 0x00100000 /* Out token package */
|
||||
#define SETUP_TOKEN_FRAME 0x00080000 /* Setup token package */
|
||||
#define STALL_FRAME 0x00040000 /* Stall handshake */
|
||||
#define NACK_FRAME 0x00020000 /* Nack handshake */
|
||||
#define NO_PID 0x00010000 /* No send PID */
|
||||
#define NO_CRC 0x00008000 /* No send CRC */
|
||||
#define HOST_COMMAND 0x00004000 /* Host command frame */
|
||||
|
||||
/* Frame status field */
|
||||
/* Receive side */
|
||||
#define FRAME_OK 0x00000000 /* Frame tranmitted or received OK */
|
||||
#define FRAME_ERROR 0x80000000 /* Error occured on frame */
|
||||
#define START_FRAME_LOST 0x40000000 /* START_FRAME_LOST */
|
||||
#define END_FRAME_LOST 0x20000000 /* END_FRAME_LOST */
|
||||
#define RX_ER_NONOCT 0x10000000 /* Rx Non Octet Aligned Packet */
|
||||
#define RX_ER_BITSTUFF 0x08000000 /* Frame Aborted --Received packet
|
||||
with bit stuff error */
|
||||
#define RX_ER_CRC 0x04000000 /* Received packet with CRC error */
|
||||
#define RX_ER_OVERUN 0x02000000 /* Over-run occured on reception */
|
||||
#define RX_ER_PID 0x01000000 /* Wrong PID received */
|
||||
/* Tranmit side */
|
||||
#define TX_ER_NAK 0x00800000 /* Received NAK handshake */
|
||||
#define TX_ER_STALL 0x00400000 /* Received STALL handshake */
|
||||
#define TX_ER_TIMEOUT 0x00200000 /* Transmit time out */
|
||||
#define TX_ER_UNDERUN 0x00100000 /* Transmit underrun */
|
||||
#define FRAME_INPROGRESS 0x00080000 /* Frame is being transmitted */
|
||||
#define ER_DATA_UNDERUN 0x00040000 /* Frame is shorter then expected */
|
||||
#define ER_DATA_OVERUN 0x00020000 /* Frame is longer then expected */
|
||||
|
||||
/* QE USB frame operation functions */
|
||||
#define frame_get_length(frm) (frm->len)
|
||||
#define frame_set_length(frm, leng) (frm->len = leng)
|
||||
#define frame_get_data(frm) (frm->data)
|
||||
#define frame_set_data(frm, dat) (frm->data = dat)
|
||||
#define frame_get_info(frm) (frm->info)
|
||||
#define frame_set_info(frm, inf) (frm->info = inf)
|
||||
#define frame_get_status(frm) (frm->status)
|
||||
#define frame_set_status(frm, stat) (frm->status = stat)
|
||||
#define frame_get_privdata(frm) (frm->privdata)
|
||||
#define frame_set_privdata(frm, dat) (frm->privdata = dat)
|
||||
|
||||
static inline void qe_frame_clean(struct qe_frame *frm)
|
||||
{
|
||||
frame_set_data(frm, NULL);
|
||||
frame_set_length(frm, 0);
|
||||
frame_set_status(frm, FRAME_OK);
|
||||
frame_set_info(frm, 0);
|
||||
frame_set_privdata(frm, NULL);
|
||||
}
|
||||
|
||||
static inline void qe_frame_init(struct qe_frame *frm)
|
||||
{
|
||||
qe_frame_clean(frm);
|
||||
INIT_LIST_HEAD(&(frm->node));
|
||||
}
|
||||
|
||||
struct qe_req {
|
||||
struct usb_request req;
|
||||
struct list_head queue;
|
||||
/* ep_queue() func will add
|
||||
a request->queue into a udc_ep->queue 'd tail */
|
||||
struct qe_ep *ep;
|
||||
unsigned mapped:1;
|
||||
};
|
||||
|
||||
struct qe_ep {
|
||||
struct usb_ep ep;
|
||||
struct list_head queue;
|
||||
struct qe_udc *udc;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
struct usb_gadget *gadget;
|
||||
|
||||
u8 state;
|
||||
|
||||
struct qe_bd __iomem *rxbase;
|
||||
struct qe_bd __iomem *n_rxbd;
|
||||
struct qe_bd __iomem *e_rxbd;
|
||||
|
||||
struct qe_bd __iomem *txbase;
|
||||
struct qe_bd __iomem *n_txbd;
|
||||
struct qe_bd __iomem *c_txbd;
|
||||
|
||||
struct qe_frame *rxframe;
|
||||
u8 *rxbuffer;
|
||||
dma_addr_t rxbuf_d;
|
||||
u8 rxbufmap;
|
||||
unsigned char localnack;
|
||||
int has_data;
|
||||
|
||||
struct qe_frame *txframe;
|
||||
struct qe_req *tx_req;
|
||||
int sent; /*data already sent */
|
||||
int last; /*data sent in the last time*/
|
||||
|
||||
u8 dir;
|
||||
u8 epnum;
|
||||
u8 tm; /* transfer mode */
|
||||
u8 data01;
|
||||
u8 init;
|
||||
|
||||
u8 already_seen;
|
||||
u8 enable_tasklet;
|
||||
u8 setup_stage;
|
||||
u32 last_io; /* timestamp */
|
||||
|
||||
char name[14];
|
||||
|
||||
unsigned double_buf:1;
|
||||
unsigned stopped:1;
|
||||
unsigned fnf:1;
|
||||
unsigned has_dma:1;
|
||||
|
||||
u8 ackwait;
|
||||
u8 dma_channel;
|
||||
u16 dma_counter;
|
||||
int lch;
|
||||
|
||||
struct timer_list timer;
|
||||
};
|
||||
|
||||
struct qe_udc {
|
||||
struct usb_gadget gadget;
|
||||
struct usb_gadget_driver *driver;
|
||||
struct device *dev;
|
||||
struct qe_ep eps[USB_MAX_ENDPOINTS];
|
||||
struct usb_ctrlrequest local_setup_buff;
|
||||
spinlock_t lock; /* lock for set/config qe_udc */
|
||||
unsigned long soc_type; /* QE or CPM soc */
|
||||
|
||||
struct qe_req *status_req; /* ep0 status request */
|
||||
|
||||
/* USB and EP Parameter Block pointer */
|
||||
struct usb_device_para __iomem *usb_param;
|
||||
struct usb_ep_para __iomem *ep_param[4];
|
||||
|
||||
u32 max_pipes; /* Device max pipes */
|
||||
u32 max_use_endpts; /* Max endpointes to be used */
|
||||
u32 bus_reset; /* Device is bus reseting */
|
||||
u32 resume_state; /* USB state to resume*/
|
||||
u32 usb_state; /* USB current state */
|
||||
u32 usb_next_state; /* USB next state */
|
||||
u32 ep0_state; /* Enpoint zero state */
|
||||
u32 ep0_dir; /* Enpoint zero direction: can be
|
||||
USB_DIR_IN or USB_DIR_OUT*/
|
||||
u32 usb_sof_count; /* SOF count */
|
||||
u32 errors; /* USB ERRORs count */
|
||||
|
||||
u8 *tmpbuf;
|
||||
u32 c_start;
|
||||
u32 c_end;
|
||||
|
||||
u8 *nullbuf;
|
||||
u8 *statusbuf;
|
||||
dma_addr_t nullp;
|
||||
u8 nullmap;
|
||||
u8 device_address; /* Device USB address */
|
||||
|
||||
unsigned int usb_clock;
|
||||
unsigned int usb_irq;
|
||||
struct usb_ctlr __iomem *usb_regs;
|
||||
|
||||
struct tasklet_struct rx_tasklet;
|
||||
|
||||
struct completion *done; /* to make sure release() is done */
|
||||
};
|
||||
|
||||
#define EP_STATE_IDLE 0
|
||||
#define EP_STATE_NACK 1
|
||||
#define EP_STATE_STALL 2
|
||||
|
||||
/*
|
||||
* transmit BD's status
|
||||
*/
|
||||
#define T_R 0x80000000 /* ready bit */
|
||||
#define T_W 0x20000000 /* wrap bit */
|
||||
#define T_I 0x10000000 /* interrupt on completion */
|
||||
#define T_L 0x08000000 /* last */
|
||||
#define T_TC 0x04000000 /* transmit CRC */
|
||||
#define T_CNF 0x02000000 /* wait for transmit confirm */
|
||||
#define T_LSP 0x01000000 /* Low-speed transaction */
|
||||
#define T_PID 0x00c00000 /* packet id */
|
||||
#define T_NAK 0x00100000 /* No ack. */
|
||||
#define T_STAL 0x00080000 /* Stall recieved */
|
||||
#define T_TO 0x00040000 /* time out */
|
||||
#define T_UN 0x00020000 /* underrun */
|
||||
|
||||
#define DEVICE_T_ERROR (T_UN | T_TO)
|
||||
#define HOST_T_ERROR (T_UN | T_TO | T_NAK | T_STAL)
|
||||
#define DEVICE_T_BD_MASK DEVICE_T_ERROR
|
||||
#define HOST_T_BD_MASK HOST_T_ERROR
|
||||
|
||||
#define T_PID_SHIFT 6
|
||||
#define T_PID_DATA0 0x00800000 /* Data 0 toggle */
|
||||
#define T_PID_DATA1 0x00c00000 /* Data 1 toggle */
|
||||
|
||||
/*
|
||||
* receive BD's status
|
||||
*/
|
||||
#define R_E 0x80000000 /* buffer empty */
|
||||
#define R_W 0x20000000 /* wrap bit */
|
||||
#define R_I 0x10000000 /* interrupt on reception */
|
||||
#define R_L 0x08000000 /* last */
|
||||
#define R_F 0x04000000 /* first */
|
||||
#define R_PID 0x00c00000 /* packet id */
|
||||
#define R_NO 0x00100000 /* Rx Non Octet Aligned Packet */
|
||||
#define R_AB 0x00080000 /* Frame Aborted */
|
||||
#define R_CR 0x00040000 /* CRC Error */
|
||||
#define R_OV 0x00020000 /* Overrun */
|
||||
|
||||
#define R_ERROR (R_NO | R_AB | R_CR | R_OV)
|
||||
#define R_BD_MASK R_ERROR
|
||||
|
||||
#define R_PID_DATA0 0x00000000
|
||||
#define R_PID_DATA1 0x00400000
|
||||
#define R_PID_SETUP 0x00800000
|
||||
|
||||
#define CPM_USB_STOP_TX 0x2e600000
|
||||
#define CPM_USB_RESTART_TX 0x2e600000
|
||||
#define CPM_USB_STOP_TX_OPCODE 0x0a
|
||||
#define CPM_USB_RESTART_TX_OPCODE 0x0b
|
||||
#define CPM_USB_EP_SHIFT 5
|
||||
|
||||
#ifndef CONFIG_CPM
|
||||
inline int cpm_command(u32 command, u8 opcode)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_QUICC_ENGINE
|
||||
inline int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol,
|
||||
u32 cmd_input)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __FSL_QE_UDC_H */
|
|
@ -23,11 +23,8 @@
|
|||
#include <linux/ioport.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/proc_fs.h>
|
||||
|
@ -44,11 +41,9 @@
|
|||
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include "fsl_usb2_udc.h"
|
||||
|
||||
|
@ -61,8 +56,8 @@
|
|||
static const char driver_name[] = "fsl-usb2-udc";
|
||||
static const char driver_desc[] = DRIVER_DESC;
|
||||
|
||||
volatile static struct usb_dr_device *dr_regs = NULL;
|
||||
volatile static struct usb_sys_interface *usb_sys_regs = NULL;
|
||||
static struct usb_dr_device *dr_regs;
|
||||
static struct usb_sys_interface *usb_sys_regs;
|
||||
|
||||
/* it is initialized in probe() */
|
||||
static struct fsl_udc *udc_controller = NULL;
|
||||
|
@ -76,16 +71,14 @@ fsl_ep0_desc = {
|
|||
.wMaxPacketSize = USB_MAX_CTRL_PAYLOAD,
|
||||
};
|
||||
|
||||
static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state);
|
||||
static int fsl_udc_resume(struct platform_device *pdev);
|
||||
static void fsl_ep_fifo_flush(struct usb_ep *_ep);
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
#define fsl_readl(addr) in_le32(addr)
|
||||
#define fsl_writel(addr, val32) out_le32(val32, addr)
|
||||
#define fsl_writel(val32, addr) out_le32(addr, val32)
|
||||
#else
|
||||
#define fsl_readl(addr) readl(addr)
|
||||
#define fsl_writel(addr, val32) writel(addr, val32)
|
||||
#define fsl_writel(val32, addr) writel(val32, addr)
|
||||
#endif
|
||||
|
||||
/********************************************************************
|
||||
|
@ -185,10 +178,6 @@ static int dr_controller_setup(struct fsl_udc *udc)
|
|||
unsigned long timeout;
|
||||
#define FSL_UDC_RESET_TIMEOUT 1000
|
||||
|
||||
/* before here, make sure dr_regs has been initialized */
|
||||
if (!udc)
|
||||
return -EINVAL;
|
||||
|
||||
/* Stop and reset the usb controller */
|
||||
tmp = fsl_readl(&dr_regs->usbcmd);
|
||||
tmp &= ~USB_CMD_RUN_STOP;
|
||||
|
@ -202,7 +191,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
|
|||
timeout = jiffies + FSL_UDC_RESET_TIMEOUT;
|
||||
while (fsl_readl(&dr_regs->usbcmd) & USB_CMD_CTRL_RESET) {
|
||||
if (time_after(jiffies, timeout)) {
|
||||
ERR("udc reset timeout! \n");
|
||||
ERR("udc reset timeout!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
cpu_relax();
|
||||
|
@ -315,7 +304,8 @@ static void dr_controller_stop(struct fsl_udc *udc)
|
|||
return;
|
||||
}
|
||||
|
||||
void dr_ep_setup(unsigned char ep_num, unsigned char dir, unsigned char ep_type)
|
||||
static void dr_ep_setup(unsigned char ep_num, unsigned char dir,
|
||||
unsigned char ep_type)
|
||||
{
|
||||
unsigned int tmp_epctrl = 0;
|
||||
|
||||
|
@ -563,7 +553,7 @@ static int fsl_ep_disable(struct usb_ep *_ep)
|
|||
/* nuke all pending requests (does flush) */
|
||||
nuke(ep, -ESHUTDOWN);
|
||||
|
||||
ep->desc = 0;
|
||||
ep->desc = NULL;
|
||||
ep->stopped = 1;
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
|
||||
|
@ -602,7 +592,7 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req)
|
|||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
|
||||
static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
|
||||
{
|
||||
int i = ep_index(ep) * 2 + ep_is_in(ep);
|
||||
u32 temp, bitmask, tmp_stat;
|
||||
|
@ -653,13 +643,16 @@ static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
|
|||
| EP_QUEUE_HEAD_STATUS_HALT));
|
||||
dQH->size_ioc_int_sts &= temp;
|
||||
|
||||
/* Ensure that updates to the QH will occure before priming. */
|
||||
wmb();
|
||||
|
||||
/* Prime endpoint by writing 1 to ENDPTPRIME */
|
||||
temp = ep_is_in(ep)
|
||||
? (1 << (ep_index(ep) + 16))
|
||||
: (1 << (ep_index(ep)));
|
||||
fsl_writel(temp, &dr_regs->endpointprime);
|
||||
out:
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fill in the dTD structure
|
||||
|
@ -710,7 +703,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
|
|||
*is_last = 0;
|
||||
|
||||
if ((*is_last) == 0)
|
||||
VDBG("multi-dtd request!\n");
|
||||
VDBG("multi-dtd request!");
|
||||
/* Fill in the transfer size; set active bit */
|
||||
swap_temp = ((*length << DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE);
|
||||
|
||||
|
@ -773,11 +766,11 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||
/* catch various bogus parameters */
|
||||
if (!_req || !req->req.complete || !req->req.buf
|
||||
|| !list_empty(&req->queue)) {
|
||||
VDBG("%s, bad params\n", __func__);
|
||||
VDBG("%s, bad params", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (unlikely(!_ep || !ep->desc)) {
|
||||
VDBG("%s, bad ep\n", __func__);
|
||||
VDBG("%s, bad ep", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
||||
|
@ -1069,7 +1062,7 @@ static int fsl_vbus_session(struct usb_gadget *gadget, int is_active)
|
|||
|
||||
udc = container_of(gadget, struct fsl_udc, gadget);
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
VDBG("VBUS %s\n", is_active ? "on" : "off");
|
||||
VDBG("VBUS %s", is_active ? "on" : "off");
|
||||
udc->vbus_active = (is_active != 0);
|
||||
if (can_pullup(udc))
|
||||
fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP),
|
||||
|
@ -1146,7 +1139,6 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
|
|||
{
|
||||
struct fsl_req *req = udc->status_req;
|
||||
struct fsl_ep *ep;
|
||||
int status = 0;
|
||||
|
||||
if (direction == EP_DIR_IN)
|
||||
udc->ep0_dir = USB_DIR_IN;
|
||||
|
@ -1164,27 +1156,21 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
|
|||
req->dtd_count = 0;
|
||||
|
||||
if (fsl_req_to_dtd(req) == 0)
|
||||
status = fsl_queue_td(ep, req);
|
||||
fsl_queue_td(ep, req);
|
||||
else
|
||||
return -ENOMEM;
|
||||
|
||||
if (status)
|
||||
ERR("Can't queue ep0 status request \n");
|
||||
list_add_tail(&req->queue, &ep->queue);
|
||||
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe)
|
||||
static void udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe)
|
||||
{
|
||||
struct fsl_ep *ep = get_ep_by_pipe(udc, pipe);
|
||||
|
||||
if (!ep->name)
|
||||
return 0;
|
||||
|
||||
nuke(ep, -ESHUTDOWN);
|
||||
|
||||
return 0;
|
||||
if (ep->name)
|
||||
nuke(ep, -ESHUTDOWN);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1208,10 +1194,8 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
|
|||
u16 index, u16 length)
|
||||
{
|
||||
u16 tmp = 0; /* Status, cpu endian */
|
||||
|
||||
struct fsl_req *req;
|
||||
struct fsl_ep *ep;
|
||||
int status = 0;
|
||||
|
||||
ep = &udc->eps[0];
|
||||
|
||||
|
@ -1250,14 +1234,10 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
|
|||
|
||||
/* prime the data phase */
|
||||
if ((fsl_req_to_dtd(req) == 0))
|
||||
status = fsl_queue_td(ep, req);
|
||||
fsl_queue_td(ep, req);
|
||||
else /* no mem */
|
||||
goto stall;
|
||||
|
||||
if (status) {
|
||||
ERR("Can't respond to getstatus request \n");
|
||||
goto stall;
|
||||
}
|
||||
list_add_tail(&req->queue, &ep->queue);
|
||||
udc->ep0_state = DATA_STATE_XMIT;
|
||||
return;
|
||||
|
@ -1397,7 +1377,7 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,
|
|||
udc->ep0_state = WAIT_FOR_SETUP;
|
||||
break;
|
||||
case WAIT_FOR_SETUP:
|
||||
ERR("Unexpect ep0 packets \n");
|
||||
ERR("Unexpect ep0 packets\n");
|
||||
break;
|
||||
default:
|
||||
ep0stall(udc);
|
||||
|
@ -1476,7 +1456,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe,
|
|||
status = -EILSEQ;
|
||||
break;
|
||||
} else
|
||||
ERR("Unknown error has occured (0x%x)!\r\n",
|
||||
ERR("Unknown error has occured (0x%x)!\n",
|
||||
errors);
|
||||
|
||||
} else if (le32_to_cpu(curr_td->size_ioc_sts)
|
||||
|
@ -1495,7 +1475,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe,
|
|||
}
|
||||
} else {
|
||||
td_complete++;
|
||||
VDBG("dTD transmitted successful ");
|
||||
VDBG("dTD transmitted successful");
|
||||
}
|
||||
|
||||
if (j != curr_req->dtd_count - 1)
|
||||
|
@ -1568,9 +1548,6 @@ static void port_change_irq(struct fsl_udc *udc)
|
|||
{
|
||||
u32 speed;
|
||||
|
||||
if (udc->bus_reset)
|
||||
udc->bus_reset = 0;
|
||||
|
||||
/* Bus resetting is finished */
|
||||
if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) {
|
||||
/* Get the speed */
|
||||
|
@ -1678,8 +1655,6 @@ static void reset_irq(struct fsl_udc *udc)
|
|||
|
||||
if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) {
|
||||
VDBG("Bus reset");
|
||||
/* Bus is reseting */
|
||||
udc->bus_reset = 1;
|
||||
/* Reset all the queues, include XD, dTD, EP queue
|
||||
* head and TR Queue */
|
||||
reset_queues(udc);
|
||||
|
@ -1768,7 +1743,7 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc)
|
|||
}
|
||||
|
||||
if (irq_src & (USB_STS_ERR | USB_STS_SYS_ERR)) {
|
||||
VDBG("Error IRQ %x ", irq_src);
|
||||
VDBG("Error IRQ %x", irq_src);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
|
@ -1799,7 +1774,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
|||
/* lock is needed but whether should use this lock or another */
|
||||
spin_lock_irqsave(&udc_controller->lock, flags);
|
||||
|
||||
driver->driver.bus = 0;
|
||||
driver->driver.bus = NULL;
|
||||
/* hook up the driver */
|
||||
udc_controller->driver = driver;
|
||||
udc_controller->gadget.dev.driver = &driver->driver;
|
||||
|
@ -1809,8 +1784,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
|||
retval = driver->bind(&udc_controller->gadget);
|
||||
if (retval) {
|
||||
VDBG("bind to %s --> %d", driver->driver.name, retval);
|
||||
udc_controller->gadget.dev.driver = 0;
|
||||
udc_controller->driver = 0;
|
||||
udc_controller->gadget.dev.driver = NULL;
|
||||
udc_controller->driver = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1819,12 +1794,12 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
|||
udc_controller->usb_state = USB_STATE_ATTACHED;
|
||||
udc_controller->ep0_state = WAIT_FOR_SETUP;
|
||||
udc_controller->ep0_dir = 0;
|
||||
printk(KERN_INFO "%s: bind to driver %s \n",
|
||||
printk(KERN_INFO "%s: bind to driver %s\n",
|
||||
udc_controller->gadget.name, driver->driver.name);
|
||||
|
||||
out:
|
||||
if (retval)
|
||||
printk("retval %d \n", retval);
|
||||
printk("gadget driver register failed %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL(usb_gadget_register_driver);
|
||||
|
@ -1842,7 +1817,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
|
|||
return -EINVAL;
|
||||
|
||||
if (udc_controller->transceiver)
|
||||
(void)otg_set_peripheral(udc_controller->transceiver, 0);
|
||||
otg_set_peripheral(udc_controller->transceiver, NULL);
|
||||
|
||||
/* stop DR, disable intr */
|
||||
dr_controller_stop(udc_controller);
|
||||
|
@ -1863,10 +1838,10 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
|
|||
|
||||
/* unbind gadget and unhook driver. */
|
||||
driver->unbind(&udc_controller->gadget);
|
||||
udc_controller->gadget.dev.driver = 0;
|
||||
udc_controller->driver = 0;
|
||||
udc_controller->gadget.dev.driver = NULL;
|
||||
udc_controller->driver = NULL;
|
||||
|
||||
printk("unregistered gadget driver '%s'\r\n", driver->driver.name);
|
||||
printk("unregistered gadget driver '%s'\n", driver->driver.name);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(usb_gadget_unregister_driver);
|
||||
|
@ -1922,7 +1897,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|||
tmp_reg = fsl_readl(&dr_regs->usbsts);
|
||||
t = scnprintf(next, size,
|
||||
"USB Status Reg:\n"
|
||||
"Dr Suspend: %d" "Reset Received: %d" "System Error: %s"
|
||||
"Dr Suspend: %d Reset Received: %d System Error: %s "
|
||||
"USB Error Interrupt: %s\n\n",
|
||||
(tmp_reg & USB_STS_SUSPEND) ? 1 : 0,
|
||||
(tmp_reg & USB_STS_RESET) ? 1 : 0,
|
||||
|
@ -1934,11 +1909,11 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|||
tmp_reg = fsl_readl(&dr_regs->usbintr);
|
||||
t = scnprintf(next, size,
|
||||
"USB Intrrupt Enable Reg:\n"
|
||||
"Sleep Enable: %d" "SOF Received Enable: %d"
|
||||
"Sleep Enable: %d SOF Received Enable: %d "
|
||||
"Reset Enable: %d\n"
|
||||
"System Error Enable: %d"
|
||||
"System Error Enable: %d "
|
||||
"Port Change Dectected Enable: %d\n"
|
||||
"USB Error Intr Enable: %d" "USB Intr Enable: %d\n\n",
|
||||
"USB Error Intr Enable: %d USB Intr Enable: %d\n\n",
|
||||
(tmp_reg & USB_INTR_DEVICE_SUSPEND) ? 1 : 0,
|
||||
(tmp_reg & USB_INTR_SOF_EN) ? 1 : 0,
|
||||
(tmp_reg & USB_INTR_RESET_EN) ? 1 : 0,
|
||||
|
@ -1951,21 +1926,21 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|||
|
||||
tmp_reg = fsl_readl(&dr_regs->frindex);
|
||||
t = scnprintf(next, size,
|
||||
"USB Frame Index Reg:" "Frame Number is 0x%x\n\n",
|
||||
"USB Frame Index Reg: Frame Number is 0x%x\n\n",
|
||||
(tmp_reg & USB_FRINDEX_MASKS));
|
||||
size -= t;
|
||||
next += t;
|
||||
|
||||
tmp_reg = fsl_readl(&dr_regs->deviceaddr);
|
||||
t = scnprintf(next, size,
|
||||
"USB Device Address Reg:" "Device Addr is 0x%x\n\n",
|
||||
"USB Device Address Reg: Device Addr is 0x%x\n\n",
|
||||
(tmp_reg & USB_DEVICE_ADDRESS_MASK));
|
||||
size -= t;
|
||||
next += t;
|
||||
|
||||
tmp_reg = fsl_readl(&dr_regs->endpointlistaddr);
|
||||
t = scnprintf(next, size,
|
||||
"USB Endpoint List Address Reg:"
|
||||
"USB Endpoint List Address Reg: "
|
||||
"Device Addr is 0x%x\n\n",
|
||||
(tmp_reg & USB_EP_LIST_ADDRESS_MASK));
|
||||
size -= t;
|
||||
|
@ -1974,11 +1949,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|||
tmp_reg = fsl_readl(&dr_regs->portsc1);
|
||||
t = scnprintf(next, size,
|
||||
"USB Port Status&Control Reg:\n"
|
||||
"Port Transceiver Type : %s" "Port Speed: %s \n"
|
||||
"PHY Low Power Suspend: %s" "Port Reset: %s"
|
||||
"Port Suspend Mode: %s \n" "Over-current Change: %s"
|
||||
"Port Transceiver Type : %s Port Speed: %s\n"
|
||||
"PHY Low Power Suspend: %s Port Reset: %s "
|
||||
"Port Suspend Mode: %s\n"
|
||||
"Over-current Change: %s "
|
||||
"Port Enable/Disable Change: %s\n"
|
||||
"Port Enabled/Disabled: %s"
|
||||
"Port Enabled/Disabled: %s "
|
||||
"Current Connect Status: %s\n\n", ( {
|
||||
char *s;
|
||||
switch (tmp_reg & PORTSCX_PTS_FSLS) {
|
||||
|
@ -2023,7 +1999,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|||
|
||||
tmp_reg = fsl_readl(&dr_regs->usbmode);
|
||||
t = scnprintf(next, size,
|
||||
"USB Mode Reg:" "Controller Mode is : %s\n\n", ( {
|
||||
"USB Mode Reg: Controller Mode is: %s\n\n", ( {
|
||||
char *s;
|
||||
switch (tmp_reg & USB_MODE_CTRL_MODE_HOST) {
|
||||
case USB_MODE_CTRL_MODE_IDLE:
|
||||
|
@ -2042,7 +2018,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|||
|
||||
tmp_reg = fsl_readl(&dr_regs->endptsetupstat);
|
||||
t = scnprintf(next, size,
|
||||
"Endpoint Setup Status Reg:" "SETUP on ep 0x%x\n\n",
|
||||
"Endpoint Setup Status Reg: SETUP on ep 0x%x\n\n",
|
||||
(tmp_reg & EP_SETUP_STATUS_MASK));
|
||||
size -= t;
|
||||
next += t;
|
||||
|
@ -2055,12 +2031,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|||
next += t;
|
||||
}
|
||||
tmp_reg = fsl_readl(&dr_regs->endpointprime);
|
||||
t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n", tmp_reg);
|
||||
t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n\n", tmp_reg);
|
||||
size -= t;
|
||||
next += t;
|
||||
|
||||
tmp_reg = usb_sys_regs->snoop1;
|
||||
t = scnprintf(next, size, "\nSnoop1 Reg : = [0x%x]\n\n", tmp_reg);
|
||||
t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg);
|
||||
size -= t;
|
||||
next += t;
|
||||
|
||||
|
@ -2084,7 +2060,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|||
} else {
|
||||
list_for_each_entry(req, &ep->queue, queue) {
|
||||
t = scnprintf(next, size,
|
||||
"req %p actual 0x%x length 0x%x buf %p\n",
|
||||
"req %p actual 0x%x length 0x%x buf %p\n",
|
||||
&req->req, req->req.actual,
|
||||
req->req.length, req->req.buf);
|
||||
size -= t;
|
||||
|
@ -2110,7 +2086,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|||
} else {
|
||||
list_for_each_entry(req, &ep->queue, queue) {
|
||||
t = scnprintf(next, size,
|
||||
"req %p actual 0x%x length"
|
||||
"req %p actual 0x%x length "
|
||||
"0x%x buf %p\n",
|
||||
&req->req, req->req.actual,
|
||||
req->req.length, req->req.buf);
|
||||
|
@ -2202,7 +2178,6 @@ static int __init struct_udc_setup(struct fsl_udc *udc,
|
|||
udc->usb_state = USB_STATE_POWERED;
|
||||
udc->ep0_dir = 0;
|
||||
udc->remote_wakeup = 0; /* default to 0 on reset */
|
||||
spin_lock_init(&udc->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2254,7 +2229,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
|||
u32 dccparams;
|
||||
|
||||
if (strcmp(pdev->name, driver_name)) {
|
||||
VDBG("Wrong device\n");
|
||||
VDBG("Wrong device");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -2264,23 +2239,26 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
spin_lock_init(&udc_controller->lock);
|
||||
udc_controller->stopped = 1;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
kfree(udc_controller);
|
||||
return -ENXIO;
|
||||
ret = -ENXIO;
|
||||
goto err_kfree;
|
||||
}
|
||||
|
||||
if (!request_mem_region(res->start, res->end - res->start + 1,
|
||||
driver_name)) {
|
||||
ERR("request mem region for %s failed \n", pdev->name);
|
||||
kfree(udc_controller);
|
||||
return -EBUSY;
|
||||
ERR("request mem region for %s failed\n", pdev->name);
|
||||
ret = -EBUSY;
|
||||
goto err_kfree;
|
||||
}
|
||||
|
||||
dr_regs = ioremap(res->start, res->end - res->start + 1);
|
||||
if (!dr_regs) {
|
||||
ret = -ENOMEM;
|
||||
goto err1;
|
||||
goto err_release_mem_region;
|
||||
}
|
||||
|
||||
usb_sys_regs = (struct usb_sys_interface *)
|
||||
|
@ -2291,7 +2269,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
|||
if (!(dccparams & DCCPARAMS_DC)) {
|
||||
ERR("This SOC doesn't support device role\n");
|
||||
ret = -ENODEV;
|
||||
goto err2;
|
||||
goto err_iounmap;
|
||||
}
|
||||
/* Get max device endpoints */
|
||||
/* DEN is bidirectional ep number, max_ep doubles the number */
|
||||
|
@ -2300,22 +2278,22 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
|||
udc_controller->irq = platform_get_irq(pdev, 0);
|
||||
if (!udc_controller->irq) {
|
||||
ret = -ENODEV;
|
||||
goto err2;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED,
|
||||
driver_name, udc_controller);
|
||||
if (ret != 0) {
|
||||
ERR("cannot request irq %d err %d \n",
|
||||
ERR("cannot request irq %d err %d\n",
|
||||
udc_controller->irq, ret);
|
||||
goto err2;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
/* Initialize the udc structure including QH member and other member */
|
||||
if (struct_udc_setup(udc_controller, pdev)) {
|
||||
ERR("Can't initialize udc data structure\n");
|
||||
ret = -ENOMEM;
|
||||
goto err3;
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
/* initialize usb hw reg except for regs for EP,
|
||||
|
@ -2336,7 +2314,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
|||
udc_controller->gadget.dev.parent = &pdev->dev;
|
||||
ret = device_register(&udc_controller->gadget.dev);
|
||||
if (ret < 0)
|
||||
goto err3;
|
||||
goto err_free_irq;
|
||||
|
||||
/* setup QH and epctrl for ep0 */
|
||||
ep0_setup(udc_controller);
|
||||
|
@ -2366,20 +2344,22 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
|||
DTD_ALIGNMENT, UDC_DMA_BOUNDARY);
|
||||
if (udc_controller->td_pool == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err4;
|
||||
goto err_unregister;
|
||||
}
|
||||
create_proc_file();
|
||||
return 0;
|
||||
|
||||
err4:
|
||||
err_unregister:
|
||||
device_unregister(&udc_controller->gadget.dev);
|
||||
err3:
|
||||
err_free_irq:
|
||||
free_irq(udc_controller->irq, udc_controller);
|
||||
err2:
|
||||
err_iounmap:
|
||||
iounmap(dr_regs);
|
||||
err1:
|
||||
err_release_mem_region:
|
||||
release_mem_region(res->start, res->end - res->start + 1);
|
||||
err_kfree:
|
||||
kfree(udc_controller);
|
||||
udc_controller = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2469,7 +2449,7 @@ module_init(udc_init);
|
|||
static void __exit udc_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&udc_driver);
|
||||
printk("%s unregistered \n", driver_desc);
|
||||
printk("%s unregistered\n", driver_desc);
|
||||
}
|
||||
|
||||
module_exit(udc_exit);
|
||||
|
|
|
@ -424,16 +424,6 @@ struct ep_td_struct {
|
|||
/* Controller dma boundary */
|
||||
#define UDC_DMA_BOUNDARY 0x1000
|
||||
|
||||
/* -----------------------------------------------------------------------*/
|
||||
/* ##### enum data
|
||||
*/
|
||||
typedef enum {
|
||||
e_ULPI,
|
||||
e_UTMI_8BIT,
|
||||
e_UTMI_16BIT,
|
||||
e_SERIAL
|
||||
} e_PhyInterface;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* ### driver private data
|
||||
|
@ -469,9 +459,9 @@ struct fsl_ep {
|
|||
#define EP_DIR_OUT 0
|
||||
|
||||
struct fsl_udc {
|
||||
|
||||
struct usb_gadget gadget;
|
||||
struct usb_gadget_driver *driver;
|
||||
struct completion *done; /* to make sure release() is done */
|
||||
struct fsl_ep *eps;
|
||||
unsigned int max_ep;
|
||||
unsigned int irq;
|
||||
|
@ -492,20 +482,13 @@ struct fsl_udc {
|
|||
size_t ep_qh_size; /* size after alignment adjustment*/
|
||||
dma_addr_t ep_qh_dma; /* dma address of QH */
|
||||
|
||||
u32 max_pipes; /* Device max pipes */
|
||||
u32 max_use_endpts; /* Max endpointes to be used */
|
||||
u32 bus_reset; /* Device is bus reseting */
|
||||
u32 max_pipes; /* Device max pipes */
|
||||
u32 resume_state; /* USB state to resume */
|
||||
u32 usb_state; /* USB current state */
|
||||
u32 usb_next_state; /* USB next state */
|
||||
u32 ep0_state; /* Endpoint zero state */
|
||||
u32 ep0_dir; /* Endpoint zero direction: can be
|
||||
USB_DIR_IN or USB_DIR_OUT */
|
||||
u32 usb_sof_count; /* SOF count */
|
||||
u32 errors; /* USB ERRORs count */
|
||||
u8 device_address; /* Device USB address */
|
||||
|
||||
struct completion *done; /* to make sure release() is done */
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
|
|
@ -151,6 +151,13 @@
|
|||
#define gadget_is_m66592(g) 0
|
||||
#endif
|
||||
|
||||
/* Freescale CPM/QE UDC SUPPORT */
|
||||
#ifdef CONFIG_USB_GADGET_FSL_QE
|
||||
#define gadget_is_fsl_qe(g) !strcmp("fsl_qe_udc", (g)->name)
|
||||
#else
|
||||
#define gadget_is_fsl_qe(g) 0
|
||||
#endif
|
||||
|
||||
|
||||
// CONFIG_USB_GADGET_SX2
|
||||
// CONFIG_USB_GADGET_AU1X00
|
||||
|
@ -216,6 +223,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
|
|||
return 0x20;
|
||||
else if (gadget_is_m66592(gadget))
|
||||
return 0x21;
|
||||
else if (gadget_is_fsl_qe(gadget))
|
||||
return 0x22;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ static struct usb_config_descriptor config_desc = {
|
|||
* power properties of the device. Is it selfpowered?
|
||||
*/
|
||||
.bmAttributes = USB_CONFIG_ATT_ONE,
|
||||
.bMaxPower = 1,
|
||||
.bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2,
|
||||
};
|
||||
|
||||
/* B.3.1 Standard AC Interface Descriptor */
|
||||
|
|
|
@ -178,6 +178,7 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
|||
|
||||
/* ep_reset() has already been called */
|
||||
ep->stopped = 0;
|
||||
ep->wedged = 0;
|
||||
ep->out_overflow = 0;
|
||||
|
||||
/* set speed-dependent max packet; may kick in high bandwidth */
|
||||
|
@ -1218,7 +1219,7 @@ static int net2280_dequeue (struct usb_ep *_ep, struct usb_request *_req)
|
|||
static int net2280_fifo_status (struct usb_ep *_ep);
|
||||
|
||||
static int
|
||||
net2280_set_halt (struct usb_ep *_ep, int value)
|
||||
net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
|
||||
{
|
||||
struct net2280_ep *ep;
|
||||
unsigned long flags;
|
||||
|
@ -1239,16 +1240,21 @@ net2280_set_halt (struct usb_ep *_ep, int value)
|
|||
else if (ep->is_in && value && net2280_fifo_status (_ep) != 0)
|
||||
retval = -EAGAIN;
|
||||
else {
|
||||
VDEBUG (ep->dev, "%s %s halt\n", _ep->name,
|
||||
value ? "set" : "clear");
|
||||
VDEBUG (ep->dev, "%s %s %s\n", _ep->name,
|
||||
value ? "set" : "clear",
|
||||
wedged ? "wedge" : "halt");
|
||||
/* set/clear, then synch memory views with the device */
|
||||
if (value) {
|
||||
if (ep->num == 0)
|
||||
ep->dev->protocol_stall = 1;
|
||||
else
|
||||
set_halt (ep);
|
||||
} else
|
||||
if (wedged)
|
||||
ep->wedged = 1;
|
||||
} else {
|
||||
clear_halt (ep);
|
||||
ep->wedged = 0;
|
||||
}
|
||||
(void) readl (&ep->regs->ep_rsp);
|
||||
}
|
||||
spin_unlock_irqrestore (&ep->dev->lock, flags);
|
||||
|
@ -1256,6 +1262,20 @@ net2280_set_halt (struct usb_ep *_ep, int value)
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
net2280_set_halt(struct usb_ep *_ep, int value)
|
||||
{
|
||||
return net2280_set_halt_and_wedge(_ep, value, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
net2280_set_wedge(struct usb_ep *_ep)
|
||||
{
|
||||
if (!_ep || _ep->name == ep0name)
|
||||
return -EINVAL;
|
||||
return net2280_set_halt_and_wedge(_ep, 1, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
net2280_fifo_status (struct usb_ep *_ep)
|
||||
{
|
||||
|
@ -1302,6 +1322,7 @@ static const struct usb_ep_ops net2280_ep_ops = {
|
|||
.dequeue = net2280_dequeue,
|
||||
|
||||
.set_halt = net2280_set_halt,
|
||||
.set_wedge = net2280_set_wedge,
|
||||
.fifo_status = net2280_fifo_status,
|
||||
.fifo_flush = net2280_fifo_flush,
|
||||
};
|
||||
|
@ -2410,9 +2431,14 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
|
|||
goto do_stall;
|
||||
if ((e = get_ep_by_addr (dev, w_index)) == 0)
|
||||
goto do_stall;
|
||||
clear_halt (e);
|
||||
if (e->wedged) {
|
||||
VDEBUG(dev, "%s wedged, halt not cleared\n",
|
||||
ep->ep.name);
|
||||
} else {
|
||||
VDEBUG(dev, "%s clear halt\n", ep->ep.name);
|
||||
clear_halt(e);
|
||||
}
|
||||
allow_status (ep);
|
||||
VDEBUG (dev, "%s clear halt\n", ep->ep.name);
|
||||
goto next_endpoints;
|
||||
}
|
||||
break;
|
||||
|
@ -2427,6 +2453,8 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
|
|||
goto do_stall;
|
||||
if ((e = get_ep_by_addr (dev, w_index)) == 0)
|
||||
goto do_stall;
|
||||
if (e->ep.name == ep0name)
|
||||
goto do_stall;
|
||||
set_halt (e);
|
||||
allow_status (ep);
|
||||
VDEBUG (dev, "%s set halt\n", ep->ep.name);
|
||||
|
|
|
@ -109,6 +109,7 @@ struct net2280_ep {
|
|||
in_fifo_validate : 1,
|
||||
out_overflow : 1,
|
||||
stopped : 1,
|
||||
wedged : 1,
|
||||
is_in : 1,
|
||||
is_iso : 1,
|
||||
responded : 1;
|
||||
|
|
|
@ -2313,6 +2313,13 @@ static int proc_otg_show(struct seq_file *s)
|
|||
|
||||
tmp = omap_readl(OTG_REV);
|
||||
if (cpu_is_omap24xx()) {
|
||||
/*
|
||||
* REVISIT: Not clear how this works on OMAP2. trans
|
||||
* is ANDed to produce bits 7 and 8, which might make
|
||||
* sense for USB_TRANSCEIVER_CTRL on OMAP1,
|
||||
* but with CONTROL_DEVCONF, these bits have something to
|
||||
* do with the frame adjustment counter and McBSP2.
|
||||
*/
|
||||
ctrl_name = "control_devconf";
|
||||
trans = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
|
||||
} else {
|
||||
|
|
|
@ -252,7 +252,7 @@ static struct usb_config_descriptor config_desc = {
|
|||
.bConfigurationValue = DEV_CONFIG_VALUE,
|
||||
.iConfiguration = 0,
|
||||
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
||||
.bMaxPower = 1 /* Self-Powered */
|
||||
.bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2,
|
||||
};
|
||||
|
||||
static struct usb_interface_descriptor intf_desc = {
|
||||
|
@ -1278,8 +1278,7 @@ unknown:
|
|||
/* respond with data transfer before status phase? */
|
||||
if (value >= 0) {
|
||||
req->length = value;
|
||||
req->zero = value < wLength
|
||||
&& (value % gadget->ep0->maxpacket) == 0;
|
||||
req->zero = value < wLength;
|
||||
value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
|
||||
if (value < 0) {
|
||||
DBG(dev, "ep_queue --> %d\n", value);
|
||||
|
@ -1477,7 +1476,6 @@ autoconf_fail:
|
|||
if (gadget->is_otg) {
|
||||
otg_desc.bmAttributes |= USB_OTG_HNP,
|
||||
config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
|
||||
config_desc.bMaxPower = 4;
|
||||
}
|
||||
|
||||
spin_lock_init(&dev->lock);
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
|
|
|
@ -1651,7 +1651,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
|||
return -EBUSY;
|
||||
|
||||
if (!driver->bind || !driver->setup
|
||||
|| driver->speed != USB_SPEED_FULL) {
|
||||
|| driver->speed < USB_SPEED_FULL) {
|
||||
printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n",
|
||||
driver->bind, driver->setup, driver->speed);
|
||||
return -EINVAL;
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "epautoconf.c"
|
||||
|
||||
#include "f_acm.c"
|
||||
#include "f_obex.c"
|
||||
#include "f_serial.c"
|
||||
#include "u_serial.c"
|
||||
|
||||
|
@ -56,6 +57,7 @@
|
|||
#define GS_VENDOR_ID 0x0525 /* NetChip */
|
||||
#define GS_PRODUCT_ID 0xa4a6 /* Linux-USB Serial Gadget */
|
||||
#define GS_CDC_PRODUCT_ID 0xa4a7 /* ... as CDC-ACM */
|
||||
#define GS_CDC_OBEX_PRODUCT_ID 0xa4a9 /* ... as CDC-OBEX */
|
||||
|
||||
/* string IDs are assigned dynamically */
|
||||
|
||||
|
@ -125,6 +127,10 @@ static int use_acm = true;
|
|||
module_param(use_acm, bool, 0);
|
||||
MODULE_PARM_DESC(use_acm, "Use CDC ACM, default=yes");
|
||||
|
||||
static int use_obex = false;
|
||||
module_param(use_obex, bool, 0);
|
||||
MODULE_PARM_DESC(use_obex, "Use CDC OBEX, default=no");
|
||||
|
||||
static unsigned n_ports = 1;
|
||||
module_param(n_ports, uint, 0);
|
||||
MODULE_PARM_DESC(n_ports, "number of ports to create, default=1");
|
||||
|
@ -139,6 +145,8 @@ static int __init serial_bind_config(struct usb_configuration *c)
|
|||
for (i = 0; i < n_ports && status == 0; i++) {
|
||||
if (use_acm)
|
||||
status = acm_bind_config(c, i);
|
||||
else if (use_obex)
|
||||
status = obex_bind_config(c, i);
|
||||
else
|
||||
status = gser_bind_config(c, i);
|
||||
}
|
||||
|
@ -151,7 +159,6 @@ static struct usb_configuration serial_config_driver = {
|
|||
/* .bConfigurationValue = f(use_acm) */
|
||||
/* .iConfiguration = DYNAMIC */
|
||||
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
|
||||
.bMaxPower = 1, /* 2 mA, minimal */
|
||||
};
|
||||
|
||||
static int __init gs_bind(struct usb_composite_dev *cdev)
|
||||
|
@ -249,6 +256,12 @@ static int __init init(void)
|
|||
device_desc.bDeviceClass = USB_CLASS_COMM;
|
||||
device_desc.idProduct =
|
||||
__constant_cpu_to_le16(GS_CDC_PRODUCT_ID);
|
||||
} else if (use_obex) {
|
||||
serial_config_driver.label = "CDC OBEX config";
|
||||
serial_config_driver.bConfigurationValue = 3;
|
||||
device_desc.bDeviceClass = USB_CLASS_COMM;
|
||||
device_desc.idProduct =
|
||||
__constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
|
||||
} else {
|
||||
serial_config_driver.label = "Generic Serial config";
|
||||
serial_config_driver.bConfigurationValue = 1;
|
||||
|
|
|
@ -873,6 +873,13 @@ struct net_device *gether_connect(struct gether *link)
|
|||
spin_lock(&dev->lock);
|
||||
dev->port_usb = link;
|
||||
link->ioport = dev;
|
||||
if (netif_running(dev->net)) {
|
||||
if (link->open)
|
||||
link->open(link);
|
||||
} else {
|
||||
if (link->close)
|
||||
link->close(link);
|
||||
}
|
||||
spin_unlock(&dev->lock);
|
||||
|
||||
netif_carrier_on(dev->net);
|
||||
|
|
|
@ -62,5 +62,6 @@ void gserial_disconnect(struct gserial *);
|
|||
/* functions are bound to configurations by a config or gadget driver */
|
||||
int acm_bind_config(struct usb_configuration *c, u8 port_num);
|
||||
int gser_bind_config(struct usb_configuration *c, u8 port_num);
|
||||
int obex_bind_config(struct usb_configuration *c, u8 port_num);
|
||||
|
||||
#endif /* __U_SERIAL_H */
|
||||
|
|
|
@ -358,7 +358,8 @@ struct debug_buffer {
|
|||
struct usb_bus *bus;
|
||||
struct mutex mutex; /* protect filling of buffer */
|
||||
size_t count; /* number of characters filled into buffer */
|
||||
char *page;
|
||||
char *output_buf;
|
||||
size_t alloc_size;
|
||||
};
|
||||
|
||||
#define speed_char(info1) ({ char tmp; \
|
||||
|
@ -488,8 +489,8 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
|
|||
|
||||
hcd = bus_to_hcd(buf->bus);
|
||||
ehci = hcd_to_ehci (hcd);
|
||||
next = buf->page;
|
||||
size = PAGE_SIZE;
|
||||
next = buf->output_buf;
|
||||
size = buf->alloc_size;
|
||||
|
||||
*next = 0;
|
||||
|
||||
|
@ -510,7 +511,7 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
|
|||
}
|
||||
spin_unlock_irqrestore (&ehci->lock, flags);
|
||||
|
||||
return strlen(buf->page);
|
||||
return strlen(buf->output_buf);
|
||||
}
|
||||
|
||||
#define DBG_SCHED_LIMIT 64
|
||||
|
@ -531,8 +532,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
|
|||
|
||||
hcd = bus_to_hcd(buf->bus);
|
||||
ehci = hcd_to_ehci (hcd);
|
||||
next = buf->page;
|
||||
size = PAGE_SIZE;
|
||||
next = buf->output_buf;
|
||||
size = buf->alloc_size;
|
||||
|
||||
temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size);
|
||||
size -= temp;
|
||||
|
@ -568,14 +569,16 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
|
|||
for (temp = 0; temp < seen_count; temp++) {
|
||||
if (seen [temp].ptr != p.ptr)
|
||||
continue;
|
||||
if (p.qh->qh_next.ptr)
|
||||
if (p.qh->qh_next.ptr) {
|
||||
temp = scnprintf (next, size,
|
||||
" ...");
|
||||
p.ptr = NULL;
|
||||
size -= temp;
|
||||
next += temp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* show more info the first time around */
|
||||
if (temp == seen_count && p.ptr) {
|
||||
if (temp == seen_count) {
|
||||
u32 scratch = hc32_to_cpup(ehci,
|
||||
&p.qh->hw_info1);
|
||||
struct ehci_qtd *qtd;
|
||||
|
@ -649,7 +652,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
|
|||
spin_unlock_irqrestore (&ehci->lock, flags);
|
||||
kfree (seen);
|
||||
|
||||
return PAGE_SIZE - size;
|
||||
return buf->alloc_size - size;
|
||||
}
|
||||
#undef DBG_SCHED_LIMIT
|
||||
|
||||
|
@ -665,14 +668,14 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
|
|||
|
||||
hcd = bus_to_hcd(buf->bus);
|
||||
ehci = hcd_to_ehci (hcd);
|
||||
next = buf->page;
|
||||
size = PAGE_SIZE;
|
||||
next = buf->output_buf;
|
||||
size = buf->alloc_size;
|
||||
|
||||
spin_lock_irqsave (&ehci->lock, flags);
|
||||
|
||||
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
|
||||
size = scnprintf (next, size,
|
||||
"bus %s, device %s (driver " DRIVER_VERSION ")\n"
|
||||
"bus %s, device %s\n"
|
||||
"%s\n"
|
||||
"SUSPENDED (no register access)\n",
|
||||
hcd->self.controller->bus->name,
|
||||
|
@ -684,7 +687,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
|
|||
/* Capability Registers */
|
||||
i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
|
||||
temp = scnprintf (next, size,
|
||||
"bus %s, device %s (driver " DRIVER_VERSION ")\n"
|
||||
"bus %s, device %s\n"
|
||||
"%s\n"
|
||||
"EHCI %x.%02x, hcd state %d\n",
|
||||
hcd->self.controller->bus->name,
|
||||
|
@ -808,7 +811,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
|
|||
done:
|
||||
spin_unlock_irqrestore (&ehci->lock, flags);
|
||||
|
||||
return PAGE_SIZE - size;
|
||||
return buf->alloc_size - size;
|
||||
}
|
||||
|
||||
static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
|
||||
|
@ -822,6 +825,7 @@ static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
|
|||
buf->bus = bus;
|
||||
buf->fill_func = fill_func;
|
||||
mutex_init(&buf->mutex);
|
||||
buf->alloc_size = PAGE_SIZE;
|
||||
}
|
||||
|
||||
return buf;
|
||||
|
@ -831,10 +835,10 @@ static int fill_buffer(struct debug_buffer *buf)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!buf->page)
|
||||
buf->page = (char *)get_zeroed_page(GFP_KERNEL);
|
||||
if (!buf->output_buf)
|
||||
buf->output_buf = (char *)vmalloc(buf->alloc_size);
|
||||
|
||||
if (!buf->page) {
|
||||
if (!buf->output_buf) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
@ -867,7 +871,7 @@ static ssize_t debug_output(struct file *file, char __user *user_buf,
|
|||
mutex_unlock(&buf->mutex);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, len, offset,
|
||||
buf->page, buf->count);
|
||||
buf->output_buf, buf->count);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
@ -879,8 +883,8 @@ static int debug_close(struct inode *inode, struct file *file)
|
|||
struct debug_buffer *buf = file->private_data;
|
||||
|
||||
if (buf) {
|
||||
if (buf->page)
|
||||
free_page((unsigned long)buf->page);
|
||||
if (buf->output_buf)
|
||||
vfree(buf->output_buf);
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
|
@ -895,10 +899,14 @@ static int debug_async_open(struct inode *inode, struct file *file)
|
|||
|
||||
static int debug_periodic_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = alloc_buffer(inode->i_private,
|
||||
fill_periodic_buffer);
|
||||
struct debug_buffer *buf;
|
||||
buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
return file->private_data ? 0 : -ENOMEM;
|
||||
buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
|
||||
file->private_data = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int debug_registers_open(struct inode *inode, struct file *file)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/ioport.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/timer.h>
|
||||
|
@ -59,7 +60,6 @@
|
|||
* providing early devices for those host controllers to talk to!
|
||||
*/
|
||||
|
||||
#define DRIVER_VERSION "10 Dec 2004"
|
||||
#define DRIVER_AUTHOR "David Brownell"
|
||||
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
|
||||
|
||||
|
@ -620,9 +620,9 @@ static int ehci_run (struct usb_hcd *hcd)
|
|||
|
||||
temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
|
||||
ehci_info (ehci,
|
||||
"USB %x.%x started, EHCI %x.%02x, driver %s%s\n",
|
||||
"USB %x.%x started, EHCI %x.%02x%s\n",
|
||||
((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
|
||||
temp >> 8, temp & 0xff, DRIVER_VERSION,
|
||||
temp >> 8, temp & 0xff,
|
||||
ignore_oc ? ", overcurrent ignored" : "");
|
||||
|
||||
ehci_writel(ehci, INTR_MASK,
|
||||
|
@ -706,7 +706,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|||
pcd_status = status;
|
||||
|
||||
/* resume root hub? */
|
||||
if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN))
|
||||
if (!(cmd & CMD_RUN))
|
||||
usb_hcd_resume_root_hub(hcd);
|
||||
|
||||
while (i--) {
|
||||
|
@ -715,8 +715,11 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|||
|
||||
if (pstatus & PORT_OWNER)
|
||||
continue;
|
||||
if (!(pstatus & PORT_RESUME)
|
||||
|| ehci->reset_done [i] != 0)
|
||||
if (!(test_bit(i, &ehci->suspended_ports) &&
|
||||
((pstatus & PORT_RESUME) ||
|
||||
!(pstatus & PORT_SUSPEND)) &&
|
||||
(pstatus & PORT_PE) &&
|
||||
ehci->reset_done[i] == 0))
|
||||
continue;
|
||||
|
||||
/* start 20 msec resume signaling from this port,
|
||||
|
@ -731,9 +734,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|||
|
||||
/* PCI errors [4.15.2.4] */
|
||||
if (unlikely ((status & STS_FATAL) != 0)) {
|
||||
dbg_cmd (ehci, "fatal", ehci_readl(ehci,
|
||||
&ehci->regs->command));
|
||||
dbg_status (ehci, "fatal", status);
|
||||
dbg_cmd(ehci, "fatal", cmd);
|
||||
dbg_status(ehci, "fatal", status);
|
||||
if (status & STS_HALT) {
|
||||
ehci_err (ehci, "fatal error\n");
|
||||
dead:
|
||||
|
@ -994,9 +996,7 @@ static int ehci_get_frame (struct usb_hcd *hcd)
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
|
||||
|
||||
MODULE_DESCRIPTION (DRIVER_INFO);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_AUTHOR (DRIVER_AUTHOR);
|
||||
MODULE_LICENSE ("GPL");
|
||||
|
||||
|
@ -1020,11 +1020,6 @@ MODULE_LICENSE ("GPL");
|
|||
#define PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_440EPX) && !defined(CONFIG_PPC_MERGE)
|
||||
#include "ehci-ppc-soc.c"
|
||||
#define PLATFORM_DRIVER ehci_ppc_soc_driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_EHCI_HCD_PPC_OF
|
||||
#include "ehci-ppc-of.c"
|
||||
#define OF_PLATFORM_DRIVER ehci_hcd_ppc_of_driver
|
||||
|
@ -1049,6 +1044,16 @@ static int __init ehci_hcd_init(void)
|
|||
{
|
||||
int retval = 0;
|
||||
|
||||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name);
|
||||
set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
|
||||
if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
|
||||
test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
|
||||
printk(KERN_WARNING "Warning! ehci_hcd should always be loaded"
|
||||
" before uhci_hcd and ohci_hcd, not after\n");
|
||||
|
||||
pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
|
||||
hcd_name,
|
||||
sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
|
||||
|
@ -1056,8 +1061,10 @@ static int __init ehci_hcd_init(void)
|
|||
|
||||
#ifdef DEBUG
|
||||
ehci_debug_root = debugfs_create_dir("ehci", NULL);
|
||||
if (!ehci_debug_root)
|
||||
return -ENOENT;
|
||||
if (!ehci_debug_root) {
|
||||
retval = -ENOENT;
|
||||
goto err_debug;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_DRIVER
|
||||
|
@ -1105,6 +1112,8 @@ clean0:
|
|||
debugfs_remove(ehci_debug_root);
|
||||
ehci_debug_root = NULL;
|
||||
#endif
|
||||
err_debug:
|
||||
clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
|
||||
return retval;
|
||||
}
|
||||
module_init(ehci_hcd_init);
|
||||
|
@ -1126,6 +1135,7 @@ static void __exit ehci_hcd_cleanup(void)
|
|||
#ifdef DEBUG
|
||||
debugfs_remove(ehci_debug_root);
|
||||
#endif
|
||||
clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
|
||||
}
|
||||
module_exit(ehci_hcd_cleanup);
|
||||
|
||||
|
|
|
@ -236,10 +236,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
|
|||
temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
|
||||
temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
|
||||
if (test_bit(i, &ehci->bus_suspended) &&
|
||||
(temp & PORT_SUSPEND)) {
|
||||
ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
|
||||
(temp & PORT_SUSPEND))
|
||||
temp |= PORT_RESUME;
|
||||
}
|
||||
ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
|
||||
}
|
||||
i = HCS_N_PORTS (ehci->hcs_params);
|
||||
|
@ -482,10 +480,9 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
|
|||
* controller by the user.
|
||||
*/
|
||||
|
||||
if ((temp & mask) != 0
|
||||
|| ((temp & PORT_RESUME) != 0
|
||||
&& time_after_eq(jiffies,
|
||||
ehci->reset_done[i]))) {
|
||||
if ((temp & mask) != 0 || test_bit(i, &ehci->port_c_suspend)
|
||||
|| (ehci->reset_done[i] && time_after_eq(
|
||||
jiffies, ehci->reset_done[i]))) {
|
||||
if (i < 7)
|
||||
buf [0] |= 1 << (i + 1);
|
||||
else
|
||||
|
@ -688,6 +685,7 @@ static int ehci_hub_control (
|
|||
/* resume completed? */
|
||||
else if (time_after_eq(jiffies,
|
||||
ehci->reset_done[wIndex])) {
|
||||
clear_bit(wIndex, &ehci->suspended_ports);
|
||||
set_bit(wIndex, &ehci->port_c_suspend);
|
||||
ehci->reset_done[wIndex] = 0;
|
||||
|
||||
|
@ -734,6 +732,9 @@ static int ehci_hub_control (
|
|||
ehci_readl(ehci, status_reg));
|
||||
}
|
||||
|
||||
if (!(temp & (PORT_RESUME|PORT_RESET)))
|
||||
ehci->reset_done[wIndex] = 0;
|
||||
|
||||
/* transfer dedicated ports to the companion hc */
|
||||
if ((temp & PORT_CONNECT) &&
|
||||
test_bit(wIndex, &ehci->companion_ports)) {
|
||||
|
@ -757,8 +758,17 @@ static int ehci_hub_control (
|
|||
}
|
||||
if (temp & PORT_PE)
|
||||
status |= 1 << USB_PORT_FEAT_ENABLE;
|
||||
if (temp & (PORT_SUSPEND|PORT_RESUME))
|
||||
|
||||
/* maybe the port was unsuspended without our knowledge */
|
||||
if (temp & (PORT_SUSPEND|PORT_RESUME)) {
|
||||
status |= 1 << USB_PORT_FEAT_SUSPEND;
|
||||
} else if (test_bit(wIndex, &ehci->suspended_ports)) {
|
||||
clear_bit(wIndex, &ehci->suspended_ports);
|
||||
ehci->reset_done[wIndex] = 0;
|
||||
if (temp & PORT_PE)
|
||||
set_bit(wIndex, &ehci->port_c_suspend);
|
||||
}
|
||||
|
||||
if (temp & PORT_OC)
|
||||
status |= 1 << USB_PORT_FEAT_OVER_CURRENT;
|
||||
if (temp & PORT_RESET)
|
||||
|
@ -803,6 +813,7 @@ static int ehci_hub_control (
|
|||
|| (temp & PORT_RESET) != 0)
|
||||
goto error;
|
||||
ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
|
||||
set_bit(wIndex, &ehci->suspended_ports);
|
||||
break;
|
||||
case USB_PORT_FEAT_POWER:
|
||||
if (HCS_PPC (ehci->hcs_params))
|
||||
|
|
|
@ -1,201 +0,0 @@
|
|||
/*
|
||||
* EHCI HCD (Host Controller Driver) for USB.
|
||||
*
|
||||
* (C) Copyright 2006-2007 Stefan Roese <sr@denx.de>, DENX Software Engineering
|
||||
*
|
||||
* Bus Glue for PPC On-Chip EHCI driver
|
||||
* Tested on AMCC 440EPx
|
||||
*
|
||||
* Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com>
|
||||
*
|
||||
* This file is licenced under the GPL.
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
extern int usb_disabled(void);
|
||||
|
||||
/* called during probe() after chip reset completes */
|
||||
static int ehci_ppc_soc_setup(struct usb_hcd *hcd)
|
||||
{
|
||||
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
||||
int retval;
|
||||
|
||||
retval = ehci_halt(ehci);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
retval = ehci_init(hcd);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
ehci->sbrn = 0x20;
|
||||
return ehci_reset(ehci);
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs
|
||||
* Context: !in_interrupt()
|
||||
*
|
||||
* Allocates basic resources for this USB host controller, and
|
||||
* then invokes the start() method for the HCD associated with it
|
||||
* through the hotplug entry's driver_data.
|
||||
*
|
||||
*/
|
||||
int usb_ehci_ppc_soc_probe(const struct hc_driver *driver,
|
||||
struct usb_hcd **hcd_out,
|
||||
struct platform_device *dev)
|
||||
{
|
||||
int retval;
|
||||
struct usb_hcd *hcd;
|
||||
struct ehci_hcd *ehci;
|
||||
|
||||
if (dev->resource[1].flags != IORESOURCE_IRQ) {
|
||||
pr_debug("resource[1] is not IORESOURCE_IRQ");
|
||||
retval = -ENOMEM;
|
||||
}
|
||||
hcd = usb_create_hcd(driver, &dev->dev, "PPC-SOC EHCI");
|
||||
if (!hcd)
|
||||
return -ENOMEM;
|
||||
hcd->rsrc_start = dev->resource[0].start;
|
||||
hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
|
||||
|
||||
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
|
||||
pr_debug("request_mem_region failed");
|
||||
retval = -EBUSY;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
|
||||
if (!hcd->regs) {
|
||||
pr_debug("ioremap failed");
|
||||
retval = -ENOMEM;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
ehci = hcd_to_ehci(hcd);
|
||||
ehci->big_endian_mmio = 1;
|
||||
ehci->big_endian_desc = 1;
|
||||
ehci->caps = hcd->regs;
|
||||
ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
|
||||
|
||||
/* cache this readonly data; minimize chip reads */
|
||||
ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
|
||||
|
||||
#if defined(CONFIG_440EPX)
|
||||
/*
|
||||
* 440EPx Errata USBH_3
|
||||
* Fix: Enable Break Memory Transfer (BMT) in INSNREG3
|
||||
*/
|
||||
out_be32((void *)((ulong)(&ehci->regs->command) + 0x8c), (1 << 0));
|
||||
ehci_dbg(ehci, "Break Memory Transfer (BMT) has beed enabled!\n");
|
||||
#endif
|
||||
|
||||
retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED);
|
||||
if (retval == 0)
|
||||
return retval;
|
||||
|
||||
iounmap(hcd->regs);
|
||||
err2:
|
||||
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||
err1:
|
||||
usb_put_hcd(hcd);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* may be called without controller electrically present */
|
||||
/* may be called with controller, bus, and devices active */
|
||||
|
||||
/**
|
||||
* usb_ehci_hcd_ppc_soc_remove - shutdown processing for PPC-SoC-based HCDs
|
||||
* @dev: USB Host Controller being removed
|
||||
* Context: !in_interrupt()
|
||||
*
|
||||
* Reverses the effect of usb_ehci_hcd_ppc_soc_probe(), first invoking
|
||||
* the HCD's stop() method. It is always called from a thread
|
||||
* context, normally "rmmod", "apmd", or something similar.
|
||||
*
|
||||
*/
|
||||
void usb_ehci_ppc_soc_remove(struct usb_hcd *hcd, struct platform_device *dev)
|
||||
{
|
||||
usb_remove_hcd(hcd);
|
||||
iounmap(hcd->regs);
|
||||
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||
usb_put_hcd(hcd);
|
||||
}
|
||||
|
||||
static const struct hc_driver ehci_ppc_soc_hc_driver = {
|
||||
.description = hcd_name,
|
||||
.product_desc = "PPC-SOC EHCI",
|
||||
.hcd_priv_size = sizeof(struct ehci_hcd),
|
||||
|
||||
/*
|
||||
* generic hardware linkage
|
||||
*/
|
||||
.irq = ehci_irq,
|
||||
.flags = HCD_MEMORY | HCD_USB2,
|
||||
|
||||
/*
|
||||
* basic lifecycle operations
|
||||
*/
|
||||
.reset = ehci_ppc_soc_setup,
|
||||
.start = ehci_run,
|
||||
.stop = ehci_stop,
|
||||
.shutdown = ehci_shutdown,
|
||||
|
||||
/*
|
||||
* managing i/o requests and associated device resources
|
||||
*/
|
||||
.urb_enqueue = ehci_urb_enqueue,
|
||||
.urb_dequeue = ehci_urb_dequeue,
|
||||
.endpoint_disable = ehci_endpoint_disable,
|
||||
|
||||
/*
|
||||
* scheduling support
|
||||
*/
|
||||
.get_frame_number = ehci_get_frame,
|
||||
|
||||
/*
|
||||
* root hub support
|
||||
*/
|
||||
.hub_status_data = ehci_hub_status_data,
|
||||
.hub_control = ehci_hub_control,
|
||||
.bus_suspend = ehci_bus_suspend,
|
||||
.bus_resume = ehci_bus_resume,
|
||||
.relinquish_port = ehci_relinquish_port,
|
||||
.port_handed_over = ehci_port_handed_over,
|
||||
};
|
||||
|
||||
static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct usb_hcd *hcd = NULL;
|
||||
int ret;
|
||||
|
||||
pr_debug("In ehci_hcd_ppc_soc_drv_probe\n");
|
||||
|
||||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
/* FIXME we only want one one probe() not two */
|
||||
ret = usb_ehci_ppc_soc_probe(&ehci_ppc_soc_hc_driver, &hcd, pdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ehci_hcd_ppc_soc_drv_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||
|
||||
/* FIXME we only want one one remove() not two */
|
||||
usb_ehci_ppc_soc_remove(hcd, pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_ALIAS("platform:ppc-soc-ehci");
|
||||
static struct platform_driver ehci_ppc_soc_driver = {
|
||||
.probe = ehci_hcd_ppc_soc_drv_probe,
|
||||
.remove = ehci_hcd_ppc_soc_drv_remove,
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "ppc-soc-ehci",
|
||||
}
|
||||
};
|
|
@ -99,6 +99,8 @@ struct ehci_hcd { /* one per controller */
|
|||
owned by the companion during a bus suspend */
|
||||
unsigned long port_c_suspend; /* which ports have
|
||||
the change-suspend feature turned on */
|
||||
unsigned long suspended_ports; /* which ports are
|
||||
suspended */
|
||||
|
||||
/* per-HC memory pools (could be per-bus, but ...) */
|
||||
struct dma_pool *qh_pool; /* qh per active urb */
|
||||
|
@ -181,14 +183,16 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
|
|||
* the async ring; just the I/O watchdog. Note that if a
|
||||
* SHRINK were pending, OFF would never be requested.
|
||||
*/
|
||||
if (timer_pending(&ehci->watchdog)
|
||||
&& ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
|
||||
& ehci->actions))
|
||||
return;
|
||||
enum ehci_timer_action oldactions = ehci->actions;
|
||||
|
||||
if (!test_and_set_bit (action, &ehci->actions)) {
|
||||
unsigned long t;
|
||||
|
||||
if (timer_pending(&ehci->watchdog)
|
||||
&& ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
|
||||
& oldactions))
|
||||
return;
|
||||
|
||||
switch (action) {
|
||||
case TIMER_IO_WATCHDOG:
|
||||
t = EHCI_IO_JIFFIES;
|
||||
|
@ -204,7 +208,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
|
|||
t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
|
||||
break;
|
||||
}
|
||||
mod_timer(&ehci->watchdog, t + jiffies);
|
||||
mod_timer(&ehci->watchdog, round_jiffies(t + jiffies));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -604,16 +608,7 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
|
|||
/*
|
||||
* Big-endian read/write functions are arch-specific.
|
||||
* Other arches can be added if/when they're needed.
|
||||
*
|
||||
* REVISIT: arch/powerpc now has readl/writel_be, so the
|
||||
* definition below can die once the 4xx support is
|
||||
* finally ported over.
|
||||
*/
|
||||
#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE)
|
||||
#define readl_be(addr) in_be32((__force unsigned *)addr)
|
||||
#define writel_be(val, addr) out_be32((__force unsigned *)addr, val)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_IXP4XX)
|
||||
#define readl_be(addr) __raw_readl((__force unsigned *)addr)
|
||||
#define writel_be(val, addr) __raw_writel(val, (__force unsigned *)addr)
|
||||
|
|
|
@ -1562,11 +1562,12 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct usb_hcd *hcd;
|
||||
struct isp116x *isp116x;
|
||||
struct resource *addr, *data;
|
||||
struct resource *addr, *data, *ires;
|
||||
void __iomem *addr_reg;
|
||||
void __iomem *data_reg;
|
||||
int irq;
|
||||
int ret = 0;
|
||||
unsigned long irqflags;
|
||||
|
||||
if (pdev->num_resources < 3) {
|
||||
ret = -ENODEV;
|
||||
|
@ -1575,12 +1576,16 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
|
|||
|
||||
data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (!addr || !data || irq < 0) {
|
||||
ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
|
||||
if (!addr || !data || !ires) {
|
||||
ret = -ENODEV;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
irq = ires->start;
|
||||
irqflags = ires->flags & IRQF_TRIGGER_MASK;
|
||||
|
||||
if (pdev->dev.dma_mask) {
|
||||
DBG("DMA not supported\n");
|
||||
ret = -EINVAL;
|
||||
|
@ -1634,7 +1639,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
|
|||
goto err6;
|
||||
}
|
||||
|
||||
ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
|
||||
ret = usb_add_hcd(hcd, irq, irqflags | IRQF_DISABLED);
|
||||
if (ret)
|
||||
goto err6;
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
|
|||
* and reading back and checking the contents are same or not
|
||||
*/
|
||||
if (reg_data != 0xFACE) {
|
||||
err("scratch register mismatch %x", reg_data);
|
||||
dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
|
||||
goto clean;
|
||||
}
|
||||
|
||||
|
@ -232,9 +232,10 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
|
|||
hcd = isp1760_register(pci_mem_phy0, length, dev->irq,
|
||||
IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
|
||||
devflags);
|
||||
pci_set_drvdata(dev, hcd);
|
||||
if (!hcd)
|
||||
if (!IS_ERR(hcd)) {
|
||||
pci_set_drvdata(dev, hcd);
|
||||
return 0;
|
||||
}
|
||||
clean:
|
||||
status = -ENODEV;
|
||||
iounmap(iobase);
|
||||
|
|
|
@ -649,7 +649,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
|
|||
ohci_dbg_sw (ohci, &next, &size,
|
||||
"bus %s, device %s\n"
|
||||
"%s\n"
|
||||
"%s version " DRIVER_VERSION "\n",
|
||||
"%s\n",
|
||||
hcd->self.controller->bus->name,
|
||||
dev_name(hcd->self.controller),
|
||||
hcd->product_desc,
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
|
||||
#include "../core/hcd.h"
|
||||
|
||||
#define DRIVER_VERSION "2006 August 04"
|
||||
#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
|
||||
#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
|
||||
|
||||
|
@ -984,10 +983,8 @@ static int ohci_restart (struct ohci_hcd *ohci)
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
|
||||
|
||||
MODULE_AUTHOR (DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION (DRIVER_INFO);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE ("GPL");
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
@ -1095,9 +1092,10 @@ static int __init ohci_hcd_mod_init(void)
|
|||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
printk (KERN_DEBUG "%s: " DRIVER_INFO "\n", hcd_name);
|
||||
printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name);
|
||||
pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name,
|
||||
sizeof (struct ed), sizeof (struct td));
|
||||
set_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
|
||||
|
||||
#ifdef DEBUG
|
||||
ohci_debug_root = debugfs_create_dir("ohci", NULL);
|
||||
|
@ -1184,6 +1182,7 @@ static int __init ohci_hcd_mod_init(void)
|
|||
error_debug:
|
||||
#endif
|
||||
|
||||
clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
|
||||
return retval;
|
||||
}
|
||||
module_init(ohci_hcd_mod_init);
|
||||
|
@ -1214,6 +1213,7 @@ static void __exit ohci_hcd_mod_exit(void)
|
|||
#ifdef DEBUG
|
||||
debugfs_remove(ohci_debug_root);
|
||||
#endif
|
||||
clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
|
||||
}
|
||||
module_exit(ohci_hcd_mod_exit);
|
||||
|
||||
|
|
|
@ -359,21 +359,24 @@ static void ohci_finish_controller_resume(struct usb_hcd *hcd)
|
|||
|
||||
/* Carry out polling-, autostop-, and autoresume-related state changes */
|
||||
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
|
||||
int any_connected)
|
||||
int any_connected, int rhsc_status)
|
||||
{
|
||||
int poll_rh = 1;
|
||||
int rhsc;
|
||||
int rhsc_enable;
|
||||
|
||||
/* Some broken controllers never turn off RHCS in the interrupt
|
||||
* status register. For their sake we won't re-enable RHSC
|
||||
* interrupts if the interrupt bit is already active.
|
||||
*/
|
||||
rhsc_enable = ohci_readl(ohci, &ohci->regs->intrenable) &
|
||||
OHCI_INTR_RHSC;
|
||||
|
||||
rhsc = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC;
|
||||
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
|
||||
|
||||
case OHCI_USB_OPER:
|
||||
/* If no status changes are pending, enable status-change
|
||||
* interrupts.
|
||||
*/
|
||||
if (!rhsc && !changed) {
|
||||
rhsc = OHCI_INTR_RHSC;
|
||||
ohci_writel(ohci, rhsc, &ohci->regs->intrenable);
|
||||
/* If no status changes are pending, enable RHSC interrupts. */
|
||||
if (!rhsc_enable && !rhsc_status && !changed) {
|
||||
rhsc_enable = OHCI_INTR_RHSC;
|
||||
ohci_writel(ohci, rhsc_enable, &ohci->regs->intrenable);
|
||||
}
|
||||
|
||||
/* Keep on polling until we know a device is connected
|
||||
|
@ -383,7 +386,7 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
|
|||
if (any_connected ||
|
||||
!device_may_wakeup(&ohci_to_hcd(ohci)
|
||||
->self.root_hub->dev)) {
|
||||
if (rhsc)
|
||||
if (rhsc_enable)
|
||||
poll_rh = 0;
|
||||
} else {
|
||||
ohci->autostop = 1;
|
||||
|
@ -396,34 +399,45 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
|
|||
ohci->autostop = 0;
|
||||
ohci->next_statechange = jiffies +
|
||||
STATECHANGE_DELAY;
|
||||
} else if (rhsc && time_after_eq(jiffies,
|
||||
} else if (time_after_eq(jiffies,
|
||||
ohci->next_statechange)
|
||||
&& !ohci->ed_rm_list
|
||||
&& !(ohci->hc_control &
|
||||
OHCI_SCHED_ENABLES)) {
|
||||
ohci_rh_suspend(ohci, 1);
|
||||
poll_rh = 0;
|
||||
if (rhsc_enable)
|
||||
poll_rh = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* if there is a port change, autostart or ask to be resumed */
|
||||
case OHCI_USB_SUSPEND:
|
||||
case OHCI_USB_RESUME:
|
||||
/* if there is a port change, autostart or ask to be resumed */
|
||||
if (changed) {
|
||||
if (ohci->autostop)
|
||||
ohci_rh_resume(ohci);
|
||||
else
|
||||
usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
|
||||
} else {
|
||||
if (!rhsc && (ohci->autostop ||
|
||||
ohci_to_hcd(ohci)->self.root_hub->
|
||||
do_remote_wakeup))
|
||||
ohci_writel(ohci, OHCI_INTR_RHSC,
|
||||
&ohci->regs->intrenable);
|
||||
|
||||
/* everything is idle, no need for polling */
|
||||
/* If remote wakeup is disabled, stop polling */
|
||||
} else if (!ohci->autostop &&
|
||||
!ohci_to_hcd(ohci)->self.root_hub->
|
||||
do_remote_wakeup) {
|
||||
poll_rh = 0;
|
||||
|
||||
} else {
|
||||
/* If no status changes are pending,
|
||||
* enable RHSC interrupts
|
||||
*/
|
||||
if (!rhsc_enable && !rhsc_status) {
|
||||
rhsc_enable = OHCI_INTR_RHSC;
|
||||
ohci_writel(ohci, rhsc_enable,
|
||||
&ohci->regs->intrenable);
|
||||
}
|
||||
/* Keep polling until RHSC is enabled */
|
||||
if (rhsc_enable)
|
||||
poll_rh = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -441,18 +455,22 @@ static inline int ohci_rh_resume(struct ohci_hcd *ohci)
|
|||
* autostop isn't used when CONFIG_PM is turned off.
|
||||
*/
|
||||
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
|
||||
int any_connected)
|
||||
int any_connected, int rhsc_status)
|
||||
{
|
||||
/* If RHSC is enabled, don't poll */
|
||||
if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
|
||||
return 0;
|
||||
|
||||
/* If no status changes are pending, enable status-change interrupts */
|
||||
if (!changed) {
|
||||
ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
/* If status changes are pending, continue polling.
|
||||
* Conversely, if no status changes are pending but the RHSC
|
||||
* status bit was set, then RHSC may be broken so continue polling.
|
||||
*/
|
||||
if (changed || rhsc_status)
|
||||
return 1;
|
||||
|
||||
/* It's safe to re-enable RHSC interrupts */
|
||||
ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
@ -467,6 +485,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
|
|||
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||
int i, changed = 0, length = 1;
|
||||
int any_connected = 0;
|
||||
int rhsc_status;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave (&ohci->lock, flags);
|
||||
|
@ -492,12 +511,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
|
|||
length++;
|
||||
}
|
||||
|
||||
/* Some broken controllers never turn off RHCS in the interrupt
|
||||
* status register. For their sake we won't re-enable RHSC
|
||||
* interrupts if the flag is already set.
|
||||
*/
|
||||
if (ohci_readl(ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC)
|
||||
changed = 1;
|
||||
/* Clear the RHSC status flag before reading the port statuses */
|
||||
ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrstatus);
|
||||
rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) &
|
||||
OHCI_INTR_RHSC;
|
||||
|
||||
/* look at each port */
|
||||
for (i = 0; i < ohci->num_ports; i++) {
|
||||
|
@ -517,7 +534,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
|
|||
}
|
||||
|
||||
hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed,
|
||||
any_connected);
|
||||
any_connected, rhsc_status);
|
||||
|
||||
done:
|
||||
spin_unlock_irqrestore (&ohci->lock, flags);
|
||||
|
|
|
@ -231,7 +231,7 @@ static int ohci_omap_init(struct usb_hcd *hcd)
|
|||
|
||||
omap_ohci_clock_power(1);
|
||||
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap15xx()) {
|
||||
omap_1510_local_bus_power(1);
|
||||
omap_1510_local_bus_init();
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
|
|||
if (IS_ERR(usb_host_ck))
|
||||
return PTR_ERR(usb_host_ck);
|
||||
|
||||
if (!cpu_is_omap1510())
|
||||
if (!cpu_is_omap15xx())
|
||||
usb_dc_ck = clk_get(0, "usb_dc_ck");
|
||||
else
|
||||
usb_dc_ck = clk_get(0, "lb_ck");
|
||||
|
|
|
@ -331,7 +331,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
|
|||
|
||||
int ret = 0, irq;
|
||||
|
||||
dev_dbg(&pdev->dev, "%s: " DRIVER_INFO " (pnx4008)\n", hcd_name);
|
||||
dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (pnx4008)\n", hcd_name);
|
||||
if (usb_disabled()) {
|
||||
err("USB is disabled");
|
||||
ret = -ENODEV;
|
||||
|
|
|
@ -540,15 +540,7 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci)
|
|||
* Big-endian read/write functions are arch-specific.
|
||||
* Other arches can be added if/when they're needed.
|
||||
*
|
||||
* REVISIT: arch/powerpc now has readl/writel_be, so the
|
||||
* definition below can die once the STB04xxx support is
|
||||
* finally ported over.
|
||||
*/
|
||||
#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE)
|
||||
#define readl_be(addr) in_be32((__force unsigned *)addr)
|
||||
#define writel_be(val, addr) out_be32((__force unsigned *)addr, val)
|
||||
#endif
|
||||
|
||||
static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci,
|
||||
__hc32 __iomem * regs)
|
||||
{
|
||||
|
|
|
@ -66,7 +66,7 @@ static unsigned short endian;
|
|||
module_param(endian, ushort, 0644);
|
||||
MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
|
||||
|
||||
static unsigned short irq_sense = INTL;
|
||||
static unsigned short irq_sense = 0xff;
|
||||
module_param(irq_sense, ushort, 0644);
|
||||
MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 "
|
||||
"(default=32)");
|
||||
|
@ -118,7 +118,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
|
|||
r8a66597_write(r8a66597, SCKE, SYSCFG0);
|
||||
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
||||
if (i++ > 1000) {
|
||||
err("register access fail.");
|
||||
printk(KERN_ERR "r8a66597: register access fail.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
} while ((tmp & SCKE) != SCKE);
|
||||
|
@ -128,7 +128,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
|
|||
r8a66597_write(r8a66597, USBE, SYSCFG0);
|
||||
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
||||
if (i++ > 1000) {
|
||||
err("register access fail.");
|
||||
printk(KERN_ERR "r8a66597: register access fail.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
} while ((tmp & USBE) != USBE);
|
||||
|
@ -141,7 +141,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
|
|||
msleep(1);
|
||||
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
||||
if (i++ > 500) {
|
||||
err("register access fail.");
|
||||
printk(KERN_ERR "r8a66597: register access fail.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
} while ((tmp & SCKE) != SCKE);
|
||||
|
@ -265,7 +265,7 @@ static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port)
|
|||
if (root_port) {
|
||||
*root_port = (devpath[0] & 0x0F) - 1;
|
||||
if (*root_port >= R8A66597_MAX_ROOT_HUB)
|
||||
err("illegal root port number");
|
||||
printk(KERN_ERR "r8a66597: Illegal root port number.\n");
|
||||
}
|
||||
if (hub_port)
|
||||
*hub_port = devpath[2] & 0x0F;
|
||||
|
@ -286,7 +286,7 @@ static u16 get_r8a66597_usb_speed(enum usb_device_speed speed)
|
|||
usbspd = HSMODE;
|
||||
break;
|
||||
default:
|
||||
err("unknown speed");
|
||||
printk(KERN_ERR "r8a66597: unknown speed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -385,7 +385,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
|
|||
struct r8a66597_device *dev;
|
||||
|
||||
if (is_hub_limit(urb->dev->devpath)) {
|
||||
err("Externel hub limit reached.");
|
||||
dev_err(&urb->dev->dev, "External hub limit reached.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -406,8 +406,9 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
|
|||
return addr;
|
||||
}
|
||||
|
||||
err("cannot communicate with a USB device more than 10.(%x)",
|
||||
r8a66597->address_map);
|
||||
dev_err(&urb->dev->dev,
|
||||
"cannot communicate with a USB device more than 10.(%x)\n",
|
||||
r8a66597->address_map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -447,7 +448,8 @@ static void r8a66597_reg_wait(struct r8a66597 *r8a66597, unsigned long reg,
|
|||
do {
|
||||
tmp = r8a66597_read(r8a66597, reg);
|
||||
if (i++ > 1000000) {
|
||||
err("register%lx, loop %x is timeout", reg, loop);
|
||||
printk(KERN_ERR "r8a66597: register%lx, loop %x "
|
||||
"is timeout\n", reg, loop);
|
||||
break;
|
||||
}
|
||||
ndelay(1);
|
||||
|
@ -675,7 +677,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
|
|||
array[i++] = 1;
|
||||
break;
|
||||
default:
|
||||
err("Illegal type");
|
||||
printk(KERN_ERR "r8a66597: Illegal type\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -705,7 +707,7 @@ static u16 get_r8a66597_type(__u8 type)
|
|||
r8a66597_type = R8A66597_ISO;
|
||||
break;
|
||||
default:
|
||||
err("Illegal type");
|
||||
printk(KERN_ERR "r8a66597: Illegal type\n");
|
||||
r8a66597_type = 0x0000;
|
||||
break;
|
||||
}
|
||||
|
@ -724,7 +726,7 @@ static u16 get_bufnum(u16 pipenum)
|
|||
else if (check_interrupt(pipenum))
|
||||
bufnum = 4 + (pipenum - 6);
|
||||
else
|
||||
err("Illegal pipenum (%d)", pipenum);
|
||||
printk(KERN_ERR "r8a66597: Illegal pipenum (%d)\n", pipenum);
|
||||
|
||||
return bufnum;
|
||||
}
|
||||
|
@ -740,7 +742,7 @@ static u16 get_buf_bsize(u16 pipenum)
|
|||
else if (check_interrupt(pipenum))
|
||||
buf_bsize = 0;
|
||||
else
|
||||
err("Illegal pipenum (%d)", pipenum);
|
||||
printk(KERN_ERR "r8a66597: Illegal pipenum (%d)\n", pipenum);
|
||||
|
||||
return buf_bsize;
|
||||
}
|
||||
|
@ -760,10 +762,12 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
|
|||
if ((r8a66597->dma_map & (1 << i)) != 0)
|
||||
continue;
|
||||
|
||||
info("address %d, EndpointAddress 0x%02x use DMA FIFO",
|
||||
usb_pipedevice(urb->pipe),
|
||||
info->dir_in ? USB_ENDPOINT_DIR_MASK + info->epnum
|
||||
: info->epnum);
|
||||
dev_info(&dev->udev->dev,
|
||||
"address %d, EndpointAddress 0x%02x use "
|
||||
"DMA FIFO\n", usb_pipedevice(urb->pipe),
|
||||
info->dir_in ?
|
||||
USB_ENDPOINT_DIR_MASK + info->epnum
|
||||
: info->epnum);
|
||||
|
||||
r8a66597->dma_map |= 1 << i;
|
||||
dev->dma_map |= 1 << i;
|
||||
|
@ -1187,7 +1191,7 @@ static int start_transfer(struct r8a66597 *r8a66597, struct r8a66597_td *td)
|
|||
prepare_status_packet(r8a66597, td);
|
||||
break;
|
||||
default:
|
||||
err("invalid type.");
|
||||
printk(KERN_ERR "r8a66597: invalid type.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1295,7 +1299,7 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum)
|
|||
if (unlikely((tmp & FRDY) == 0)) {
|
||||
pipe_stop(r8a66597, td->pipe);
|
||||
pipe_irq_disable(r8a66597, pipenum);
|
||||
err("in fifo not ready (%d)", pipenum);
|
||||
printk(KERN_ERR "r8a66597: in fifo not ready (%d)\n", pipenum);
|
||||
finish_request(r8a66597, td, pipenum, td->urb, -EPIPE);
|
||||
return;
|
||||
}
|
||||
|
@ -1370,7 +1374,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum)
|
|||
if (unlikely((tmp & FRDY) == 0)) {
|
||||
pipe_stop(r8a66597, td->pipe);
|
||||
pipe_irq_disable(r8a66597, pipenum);
|
||||
err("out write fifo not ready. (%d)", pipenum);
|
||||
printk(KERN_ERR "r8a66597: out fifo not ready (%d)\n", pipenum);
|
||||
finish_request(r8a66597, td, pipenum, urb, -EPIPE);
|
||||
return;
|
||||
}
|
||||
|
@ -2005,7 +2009,7 @@ static struct r8a66597_device *get_r8a66597_device(struct r8a66597 *r8a66597,
|
|||
return dev;
|
||||
}
|
||||
|
||||
err("get_r8a66597_device fail.(%d)\n", addr);
|
||||
printk(KERN_ERR "r8a66597: get_r8a66597_device fail.(%d)\n", addr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2263,7 +2267,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
|
|||
#define resource_len(r) (((r)->end - (r)->start) + 1)
|
||||
static int __init r8a66597_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res = NULL;
|
||||
struct resource *res = NULL, *ires;
|
||||
int irq = -1;
|
||||
void __iomem *reg = NULL;
|
||||
struct usb_hcd *hcd = NULL;
|
||||
|
@ -2274,7 +2278,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
|
|||
|
||||
if (pdev->dev.dma_mask) {
|
||||
ret = -EINVAL;
|
||||
err("dma not support");
|
||||
dev_err(&pdev->dev, "dma not supported\n");
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
|
@ -2282,21 +2286,25 @@ static int __init r8a66597_probe(struct platform_device *pdev)
|
|||
(char *)hcd_name);
|
||||
if (!res) {
|
||||
ret = -ENODEV;
|
||||
err("platform_get_resource_byname error.");
|
||||
dev_err(&pdev->dev, "platform_get_resource_byname error.\n");
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!ires) {
|
||||
ret = -ENODEV;
|
||||
err("platform_get_irq error.");
|
||||
dev_err(&pdev->dev,
|
||||
"platform_get_resource IORESOURCE_IRQ error.\n");
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
irq = ires->start;
|
||||
irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
|
||||
|
||||
reg = ioremap(res->start, resource_len(res));
|
||||
if (reg == NULL) {
|
||||
ret = -ENOMEM;
|
||||
err("ioremap error.");
|
||||
dev_err(&pdev->dev, "ioremap error.\n");
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
|
@ -2304,7 +2312,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
|
|||
hcd = usb_create_hcd(&r8a66597_hc_driver, &pdev->dev, (char *)hcd_name);
|
||||
if (!hcd) {
|
||||
ret = -ENOMEM;
|
||||
err("Failed to create hcd");
|
||||
dev_err(&pdev->dev, "Failed to create hcd\n");
|
||||
goto clean_up;
|
||||
}
|
||||
r8a66597 = hcd_to_r8a66597(hcd);
|
||||
|
@ -2329,13 +2337,33 @@ static int __init r8a66597_probe(struct platform_device *pdev)
|
|||
INIT_LIST_HEAD(&r8a66597->child_device);
|
||||
|
||||
hcd->rsrc_start = res->start;
|
||||
if (irq_sense == INTL)
|
||||
irq_trigger = IRQF_TRIGGER_LOW;
|
||||
else
|
||||
irq_trigger = IRQF_TRIGGER_FALLING;
|
||||
|
||||
/* irq_sense setting on cmdline takes precedence over resource
|
||||
* settings, so the introduction of irqflags in IRQ resourse
|
||||
* won't disturb existing setups */
|
||||
switch (irq_sense) {
|
||||
case INTL:
|
||||
irq_trigger = IRQF_TRIGGER_LOW;
|
||||
break;
|
||||
case 0:
|
||||
irq_trigger = IRQF_TRIGGER_FALLING;
|
||||
break;
|
||||
case 0xff:
|
||||
if (irq_trigger)
|
||||
irq_sense = (irq_trigger & IRQF_TRIGGER_LOW) ?
|
||||
INTL : 0;
|
||||
else {
|
||||
irq_sense = INTL;
|
||||
irq_trigger = IRQF_TRIGGER_LOW;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "Unknown irq_sense value.\n");
|
||||
}
|
||||
|
||||
ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
|
||||
if (ret != 0) {
|
||||
err("Failed to add hcd");
|
||||
dev_err(&pdev->dev, "Failed to add hcd\n");
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
|
@ -2364,7 +2392,8 @@ static int __init r8a66597_init(void)
|
|||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
info("driver %s, %s", hcd_name, DRIVER_VERSION);
|
||||
printk(KERN_INFO KBUILD_MODNAME ": driver %s, %s\n", hcd_name,
|
||||
DRIVER_VERSION);
|
||||
return platform_driver_register(&r8a66597_driver);
|
||||
}
|
||||
module_init(r8a66597_init);
|
||||
|
|
|
@ -1620,22 +1620,26 @@ sl811h_probe(struct platform_device *dev)
|
|||
{
|
||||
struct usb_hcd *hcd;
|
||||
struct sl811 *sl811;
|
||||
struct resource *addr, *data;
|
||||
struct resource *addr, *data, *ires;
|
||||
int irq;
|
||||
void __iomem *addr_reg;
|
||||
void __iomem *data_reg;
|
||||
int retval;
|
||||
u8 tmp, ioaddr = 0;
|
||||
unsigned long irqflags;
|
||||
|
||||
/* basic sanity checks first. board-specific init logic should
|
||||
* have initialized these three resources and probably board
|
||||
* specific platform_data. we don't probe for IRQs, and do only
|
||||
* minimal sanity checking.
|
||||
*/
|
||||
irq = platform_get_irq(dev, 0);
|
||||
if (dev->num_resources < 3 || irq < 0)
|
||||
ires = platform_get_resource(dev, IORESOURCE_IRQ, 0);
|
||||
if (dev->num_resources < 3 || !ires)
|
||||
return -ENODEV;
|
||||
|
||||
irq = ires->start;
|
||||
irqflags = ires->flags & IRQF_TRIGGER_MASK;
|
||||
|
||||
/* refuse to confuse usbcore */
|
||||
if (dev->dev.dma_mask) {
|
||||
DBG("no we won't dma\n");
|
||||
|
@ -1717,8 +1721,11 @@ sl811h_probe(struct platform_device *dev)
|
|||
* triggers (e.g. most ARM CPUs). Initial driver stress testing
|
||||
* was on a system with single edge triggering, so most sorts of
|
||||
* triggering arrangement should work.
|
||||
*
|
||||
* Use resource IRQ flags if set by platform device setup.
|
||||
*/
|
||||
retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
|
||||
irqflags |= IRQF_SHARED;
|
||||
retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | irqflags);
|
||||
if (retval != 0)
|
||||
goto err6;
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
/*
|
||||
* Version Information
|
||||
*/
|
||||
#define DRIVER_VERSION "v3.0"
|
||||
#define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \
|
||||
Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \
|
||||
Alan Stern"
|
||||
|
@ -951,12 +950,13 @@ static int __init uhci_hcd_init(void)
|
|||
{
|
||||
int retval = -ENOMEM;
|
||||
|
||||
printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "%s\n",
|
||||
ignore_oc ? ", overcurrent ignored" : "");
|
||||
|
||||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
printk(KERN_INFO "uhci_hcd: " DRIVER_DESC "%s\n",
|
||||
ignore_oc ? ", overcurrent ignored" : "");
|
||||
set_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
|
||||
|
||||
if (DEBUG_CONFIGURED) {
|
||||
errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL);
|
||||
if (!errbuf)
|
||||
|
@ -988,6 +988,7 @@ debug_failed:
|
|||
|
||||
errbuf_failed:
|
||||
|
||||
clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -997,6 +998,7 @@ static void __exit uhci_hcd_cleanup(void)
|
|||
kmem_cache_destroy(uhci_up_cachep);
|
||||
debugfs_remove(uhci_debugfs_root);
|
||||
kfree(errbuf);
|
||||
clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
|
||||
}
|
||||
|
||||
module_init(uhci_hcd_init);
|
||||
|
|
|
@ -1065,13 +1065,18 @@ static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
|
|||
}
|
||||
if (exponent < 0)
|
||||
return -EINVAL;
|
||||
qh->period = 1 << exponent;
|
||||
qh->skel = SKEL_INDEX(exponent);
|
||||
|
||||
/* For now, interrupt phase is fixed by the layout
|
||||
* of the QH lists. */
|
||||
qh->phase = (qh->period / 2) & (MAX_PHASE - 1);
|
||||
ret = uhci_check_bandwidth(uhci, qh);
|
||||
/* If the slot is full, try a lower period */
|
||||
do {
|
||||
qh->period = 1 << exponent;
|
||||
qh->skel = SKEL_INDEX(exponent);
|
||||
|
||||
/* For now, interrupt phase is fixed by the layout
|
||||
* of the QH lists.
|
||||
*/
|
||||
qh->phase = (qh->period / 2) & (MAX_PHASE - 1);
|
||||
ret = uhci_check_bandwidth(uhci, qh);
|
||||
} while (ret != 0 && --exponent >= 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else if (qh->period > urb->interval)
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче