You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'usb-for-v4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes: usb: changes for v4.14 merge window Not a big pull request this time around. Only 49 non-merge commits. This pull request is, however, all over the place. Most of the changes are in the bdc driver adding support for USB Phy layer and PM. Renesas adds support for R-Car H3 ES2.0 and R-Car M3-W SoCs. Also here is PM_RUNTIME support for dwc3-keystone. UDC Core got a DMA unmap fix to make sure we only unmap requests that were, indeed, mapped. Other than these, we have a lot of cleanups, many of them adding 'const' to several places.
This commit is contained in:
@@ -12,3 +12,6 @@ Description:
|
||||
Ethernet over USB link
|
||||
dev_addr - MAC address of device's end of this
|
||||
Ethernet over USB link
|
||||
class - USB interface class, default is 02 (hex)
|
||||
subclass - USB interface subclass, default is 06 (hex)
|
||||
protocol - USB interface protocol, default is 00 (hex)
|
||||
|
||||
@@ -31,6 +31,7 @@ Required properties:
|
||||
../interrupt-controller/interrupts.txt
|
||||
|
||||
Optional sub-nodes:
|
||||
- phys : Contains a phandle to the USB PHY.
|
||||
- regulators : Contains sub-nodes for each of the regulators supplied by
|
||||
the device. The regulators are bound using their names listed below:
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
Broadcom USB Device Controller (BDC)
|
||||
====================================
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: must be one of:
|
||||
"brcm,bdc-v0.16"
|
||||
"brcm,bdc"
|
||||
- reg: the base register address and length
|
||||
- interrupts: the interrupt line for this controller
|
||||
|
||||
Optional properties:
|
||||
|
||||
On Broadcom STB platforms, these properties are required:
|
||||
|
||||
- phys: phandle to one or two USB PHY blocks
|
||||
NOTE: Some SoC's have a single phy and some have
|
||||
USB 2.0 and USB 3.0 phys
|
||||
- clocks: phandle to the functional clock of this block
|
||||
|
||||
Example:
|
||||
|
||||
bdc@f0b02000 {
|
||||
compatible = "brcm,bdc-v0.16";
|
||||
reg = <0xf0b02000 0xfc4>;
|
||||
interrupts = <0x0 0x60 0x0>;
|
||||
phys = <&usbphy_0 0x0>;
|
||||
clocks = <&sw_usbd>;
|
||||
};
|
||||
@@ -12,8 +12,21 @@ Required properties:
|
||||
MPU.
|
||||
- ranges: allows valid 1:1 translation between child's address space and
|
||||
parent's address space.
|
||||
- clocks: Clock IDs array as required by the controller.
|
||||
- clock-names: names of clocks correseponding to IDs in the clock property.
|
||||
|
||||
SoC-specific Required Properties:
|
||||
The following are mandatory properties for Keystone 2 66AK2HK, 66AK2L and 66AK2E
|
||||
SoCs only:
|
||||
|
||||
- clocks: Clock ID for USB functional clock.
|
||||
- clock-names: Must be "usb".
|
||||
|
||||
|
||||
The following are mandatory properties for Keystone 2 66AK2G SoCs only:
|
||||
|
||||
- power-domains: Should contain a phandle to a PM domain provider node
|
||||
and an args specifier containing the USB device id
|
||||
value. This property is as per the binding,
|
||||
Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
|
||||
|
||||
Sub-nodes:
|
||||
The dwc3 core should be added as subnode to Keystone DWC3 glue.
|
||||
|
||||
@@ -3,20 +3,30 @@ Renesas Electronics USB3.0 Peripheral driver
|
||||
Required properties:
|
||||
- compatible: Must contain one of the following:
|
||||
- "renesas,r8a7795-usb3-peri"
|
||||
- "renesas,r8a7796-usb3-peri"
|
||||
- "renesas,rcar-gen3-usb3-peri" for a generic R-Car Gen3 compatible
|
||||
device
|
||||
|
||||
When compatible with the generic version, nodes must list the
|
||||
SoC-specific version corresponding to the platform first
|
||||
followed by the generic version.
|
||||
|
||||
- reg: Base address and length of the register for the USB3.0 Peripheral
|
||||
- interrupts: Interrupt specifier for the USB3.0 Peripheral
|
||||
- clocks: clock phandle and specifier pair
|
||||
|
||||
Example:
|
||||
Example of R-Car H3 ES1.x:
|
||||
usb3_peri0: usb@ee020000 {
|
||||
compatible = "renesas,r8a7795-usb3-peri";
|
||||
compatible = "renesas,r8a7795-usb3-peri",
|
||||
"renesas,rcar-gen3-usb3-peri";
|
||||
reg = <0 0xee020000 0 0x400>;
|
||||
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 328>;
|
||||
};
|
||||
|
||||
usb3_peri1: usb@ee060000 {
|
||||
compatible = "renesas,r8a7795-usb3-peri";
|
||||
compatible = "renesas,r8a7795-usb3-peri",
|
||||
"renesas,rcar-gen3-usb3-peri";
|
||||
reg = <0 0xee060000 0 0x400>;
|
||||
interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 327>;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/usb/phy.h>
|
||||
|
||||
#include <linux/mfd/wm831x/core.h>
|
||||
#include <linux/mfd/wm831x/auxadc.h>
|
||||
@@ -31,6 +32,8 @@ struct wm831x_power {
|
||||
char usb_name[20];
|
||||
char battery_name[20];
|
||||
bool have_battery;
|
||||
struct usb_phy *usb_phy;
|
||||
struct notifier_block usb_notify;
|
||||
};
|
||||
|
||||
static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
|
||||
@@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = {
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
};
|
||||
|
||||
/* In milliamps */
|
||||
static const unsigned int wm831x_usb_limits[] = {
|
||||
0,
|
||||
2,
|
||||
100,
|
||||
500,
|
||||
900,
|
||||
1500,
|
||||
1800,
|
||||
550,
|
||||
};
|
||||
|
||||
static int wm831x_usb_limit_change(struct notifier_block *nb,
|
||||
unsigned long limit, void *data)
|
||||
{
|
||||
struct wm831x_power *wm831x_power = container_of(nb,
|
||||
struct wm831x_power,
|
||||
usb_notify);
|
||||
unsigned int i, best;
|
||||
|
||||
/* Find the highest supported limit */
|
||||
best = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
|
||||
if (limit >= wm831x_usb_limits[i] &&
|
||||
wm831x_usb_limits[best] < wm831x_usb_limits[i])
|
||||
best = i;
|
||||
}
|
||||
|
||||
dev_dbg(wm831x_power->wm831x->dev,
|
||||
"Limiting USB current to %umA", wm831x_usb_limits[best]);
|
||||
|
||||
wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
|
||||
WM831X_USB_ILIM_MASK, best);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Battery properties
|
||||
*********************************************************************/
|
||||
@@ -607,6 +647,33 @@ static int wm831x_power_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
power->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "phys", 0);
|
||||
ret = PTR_ERR_OR_ZERO(power->usb_phy);
|
||||
|
||||
switch (ret) {
|
||||
case 0:
|
||||
power->usb_notify.notifier_call = wm831x_usb_limit_change;
|
||||
ret = usb_register_notifier(power->usb_phy, &power->usb_notify);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register notifier: %d\n",
|
||||
ret);
|
||||
goto err_bat_irq;
|
||||
}
|
||||
break;
|
||||
case -EINVAL:
|
||||
case -ENODEV:
|
||||
/* ignore missing usb-phy, it's optional */
|
||||
power->usb_phy = NULL;
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "Failed to find USB phy: %d\n", ret);
|
||||
/* fall-through */
|
||||
case -EPROBE_DEFER:
|
||||
goto err_bat_irq;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err_bat_irq:
|
||||
@@ -637,6 +704,11 @@ static int wm831x_power_remove(struct platform_device *pdev)
|
||||
struct wm831x *wm831x = wm831x_power->wm831x;
|
||||
int irq, i;
|
||||
|
||||
if (wm831x_power->usb_phy) {
|
||||
usb_unregister_notifier(wm831x_power->usb_phy,
|
||||
&wm831x_power->usb_notify);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
|
||||
irq = wm831x_irq(wm831x,
|
||||
platform_get_irq_byname(pdev,
|
||||
|
||||
@@ -4179,7 +4179,7 @@ static int dwc2_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct usb_ep_ops dwc2_hsotg_ep_ops = {
|
||||
static const struct usb_ep_ops dwc2_hsotg_ep_ops = {
|
||||
.enable = dwc2_hsotg_ep_enable,
|
||||
.disable = dwc2_hsotg_ep_disable,
|
||||
.alloc_request = dwc2_hsotg_ep_alloc_request,
|
||||
|
||||
@@ -4388,6 +4388,9 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
|
||||
|
||||
spin_lock_irqsave(&hsotg->lock, flags);
|
||||
|
||||
if (dwc2_is_device_mode(hsotg))
|
||||
goto unlock;
|
||||
|
||||
if (hsotg->lx_state != DWC2_L0)
|
||||
goto unlock;
|
||||
|
||||
@@ -4446,6 +4449,9 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
|
||||
|
||||
spin_lock_irqsave(&hsotg->lock, flags);
|
||||
|
||||
if (dwc2_is_device_mode(hsotg))
|
||||
goto unlock;
|
||||
|
||||
if (hsotg->lx_state != DWC2_L2)
|
||||
goto unlock;
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -23,6 +22,7 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
/* USBSS register offsets */
|
||||
#define USBSS_REVISION 0x0000
|
||||
@@ -41,7 +41,6 @@
|
||||
|
||||
struct dwc3_keystone {
|
||||
struct device *dev;
|
||||
struct clk *clk;
|
||||
void __iomem *usbss;
|
||||
};
|
||||
|
||||
@@ -106,17 +105,13 @@ static int kdwc3_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(kdwc->usbss))
|
||||
return PTR_ERR(kdwc->usbss);
|
||||
|
||||
kdwc->clk = devm_clk_get(kdwc->dev, "usb");
|
||||
if (IS_ERR(kdwc->clk)) {
|
||||
dev_err(kdwc->dev, "unable to get usb clock\n");
|
||||
return PTR_ERR(kdwc->clk);
|
||||
}
|
||||
pm_runtime_enable(kdwc->dev);
|
||||
|
||||
error = clk_prepare_enable(kdwc->clk);
|
||||
error = pm_runtime_get_sync(kdwc->dev);
|
||||
if (error < 0) {
|
||||
dev_err(kdwc->dev, "unable to enable usb clock, error %d\n",
|
||||
dev_err(kdwc->dev, "pm_runtime_get_sync failed, error %d\n",
|
||||
error);
|
||||
return error;
|
||||
goto err_irq;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
@@ -147,7 +142,8 @@ static int kdwc3_probe(struct platform_device *pdev)
|
||||
err_core:
|
||||
kdwc3_disable_irqs(kdwc);
|
||||
err_irq:
|
||||
clk_disable_unprepare(kdwc->clk);
|
||||
pm_runtime_put_sync(kdwc->dev);
|
||||
pm_runtime_disable(kdwc->dev);
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -167,7 +163,9 @@ static int kdwc3_remove(struct platform_device *pdev)
|
||||
|
||||
kdwc3_disable_irqs(kdwc);
|
||||
device_for_each_child(&pdev->dev, NULL, kdwc3_remove_core);
|
||||
clk_disable_unprepare(kdwc->clk);
|
||||
pm_runtime_put_sync(kdwc->dev);
|
||||
pm_runtime_disable(kdwc->dev);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
@@ -96,7 +95,8 @@ static int dwc3_of_simple_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, simple);
|
||||
simple->dev = dev;
|
||||
|
||||
ret = dwc3_of_simple_clk_init(simple, of_clk_get_parent_count(np));
|
||||
ret = dwc3_of_simple_clk_init(simple, of_count_phandle_with_args(np,
|
||||
"clocks", "#clock-cells"));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -478,8 +478,8 @@ static int dwc3_omap_probe(struct platform_device *pdev)
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(dev, "missing IRQ resource\n");
|
||||
return -EINVAL;
|
||||
dev_err(dev, "missing IRQ resource: %d\n", irq);
|
||||
return irq;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
@@ -130,7 +130,7 @@ config USB_GADGET_STORAGE_NUM_BUFFERS
|
||||
|
||||
config U_SERIAL_CONSOLE
|
||||
bool "Serial gadget console support"
|
||||
depends on USB_G_SERIAL
|
||||
depends on USB_U_SERIAL
|
||||
help
|
||||
It supports the serial gadget can be used as a console.
|
||||
|
||||
|
||||
@@ -961,10 +961,9 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
|
||||
/* In the meantime, endpoint got disabled or changed. */
|
||||
ret = -ESHUTDOWN;
|
||||
} else if (halt) {
|
||||
/* Halt */
|
||||
if (likely(epfile->ep == ep) && !WARN_ON(!ep->ep))
|
||||
usb_ep_set_halt(ep->ep);
|
||||
ret = -EBADMSG;
|
||||
ret = usb_ep_set_halt(ep->ep);
|
||||
if (!ret)
|
||||
ret = -EBADMSG;
|
||||
} else if (unlikely(data_len == -EINVAL)) {
|
||||
/*
|
||||
* Sanity Check: even though data_len can't be used
|
||||
|
||||
@@ -44,6 +44,7 @@ struct f_hidg {
|
||||
/* configuration */
|
||||
unsigned char bInterfaceSubClass;
|
||||
unsigned char bInterfaceProtocol;
|
||||
unsigned char protocol;
|
||||
unsigned short report_desc_length;
|
||||
char *report_desc;
|
||||
unsigned short report_length;
|
||||
@@ -527,7 +528,9 @@ static int hidg_setup(struct usb_function *f,
|
||||
case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
|
||||
| HID_REQ_GET_PROTOCOL):
|
||||
VDBG(cdev, "get_protocol\n");
|
||||
goto stall;
|
||||
length = min_t(unsigned int, length, 1);
|
||||
((u8 *) req->buf)[0] = hidg->protocol;
|
||||
goto respond;
|
||||
break;
|
||||
|
||||
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
|
||||
@@ -539,6 +542,17 @@ static int hidg_setup(struct usb_function *f,
|
||||
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
|
||||
| HID_REQ_SET_PROTOCOL):
|
||||
VDBG(cdev, "set_protocol\n");
|
||||
if (value > HID_REPORT_PROTOCOL)
|
||||
goto stall;
|
||||
length = 0;
|
||||
/*
|
||||
* We assume that programs implementing the Boot protocol
|
||||
* are also compatible with the Report Protocol
|
||||
*/
|
||||
if (hidg->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
|
||||
hidg->protocol = value;
|
||||
goto respond;
|
||||
}
|
||||
goto stall;
|
||||
break;
|
||||
|
||||
@@ -768,6 +782,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
/* set descriptor dynamic values */
|
||||
hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
|
||||
hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
|
||||
hidg->protocol = HID_REPORT_PROTOCOL;
|
||||
hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
|
||||
hidg_ss_in_comp_desc.wBytesPerInterval =
|
||||
cpu_to_le16(hidg->report_length);
|
||||
|
||||
@@ -98,6 +98,7 @@ struct f_midi {
|
||||
DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *);
|
||||
spinlock_t transmit_lock;
|
||||
unsigned int in_last_port;
|
||||
unsigned char free_ref;
|
||||
|
||||
struct gmidi_in_port in_ports_array[/* in_ports */];
|
||||
};
|
||||
@@ -108,6 +109,7 @@ static inline struct f_midi *func_to_midi(struct usb_function *f)
|
||||
}
|
||||
|
||||
static void f_midi_transmit(struct f_midi *midi);
|
||||
static void f_midi_rmidi_free(struct snd_rawmidi *rmidi);
|
||||
|
||||
DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);
|
||||
DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
|
||||
@@ -163,6 +165,13 @@ static struct usb_endpoint_descriptor bulk_out_desc = {
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor bulk_out_ss_comp_desc = {
|
||||
.bLength = sizeof(bulk_out_ss_comp_desc),
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
/* .bMaxBurst = 0, */
|
||||
/* .bmAttributes = 0, */
|
||||
};
|
||||
|
||||
/* B.5.2 Class-specific MS Bulk OUT Endpoint Descriptor */
|
||||
static struct usb_ms_endpoint_descriptor_16 ms_out_desc = {
|
||||
/* .bLength = DYNAMIC */
|
||||
@@ -180,6 +189,13 @@ static struct usb_endpoint_descriptor bulk_in_desc = {
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor bulk_in_ss_comp_desc = {
|
||||
.bLength = sizeof(bulk_in_ss_comp_desc),
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
/* .bMaxBurst = 0, */
|
||||
/* .bmAttributes = 0, */
|
||||
};
|
||||
|
||||
/* B.6.2 Class-specific MS Bulk IN Endpoint Descriptor */
|
||||
static struct usb_ms_endpoint_descriptor_16 ms_in_desc = {
|
||||
/* .bLength = DYNAMIC */
|
||||
@@ -755,13 +771,13 @@ static void f_midi_out_trigger(struct snd_rawmidi_substream *substream, int up)
|
||||
clear_bit(substream->number, &midi->out_triggered);
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_ops gmidi_in_ops = {
|
||||
static const struct snd_rawmidi_ops gmidi_in_ops = {
|
||||
.open = f_midi_in_open,
|
||||
.close = f_midi_in_close,
|
||||
.trigger = f_midi_in_trigger,
|
||||
};
|
||||
|
||||
static struct snd_rawmidi_ops gmidi_out_ops = {
|
||||
static const struct snd_rawmidi_ops gmidi_out_ops = {
|
||||
.open = f_midi_out_open,
|
||||
.close = f_midi_out_close,
|
||||
.trigger = f_midi_out_trigger
|
||||
@@ -818,6 +834,8 @@ static int f_midi_register_card(struct f_midi *midi)
|
||||
SNDRV_RAWMIDI_INFO_INPUT |
|
||||
SNDRV_RAWMIDI_INFO_DUPLEX;
|
||||
rmidi->private_data = midi;
|
||||
rmidi->private_free = f_midi_rmidi_free;
|
||||
midi->free_ref++;
|
||||
|
||||
/*
|
||||
* Yes, rawmidi OUTPUT = USB IN, and rawmidi INPUT = USB OUT.
|
||||
@@ -853,7 +871,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
struct usb_composite_dev *cdev = c->cdev;
|
||||
struct f_midi *midi = func_to_midi(f);
|
||||
struct usb_string *us;
|
||||
int status, n, jack = 1, i = 0;
|
||||
int status, n, jack = 1, i = 0, endpoint_descriptor_index = 0;
|
||||
|
||||
midi->gadget = cdev->gadget;
|
||||
tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi);
|
||||
@@ -895,7 +913,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
goto fail;
|
||||
|
||||
/* allocate temporary function list */
|
||||
midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function),
|
||||
midi_function = kcalloc((MAX_PORTS * 4) + 11, sizeof(*midi_function),
|
||||
GFP_KERNEL);
|
||||
if (!midi_function) {
|
||||
status = -ENOMEM;
|
||||
@@ -985,6 +1003,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
ms_in_desc.bNumEmbMIDIJack = midi->out_ports;
|
||||
|
||||
/* ... and add them to the list */
|
||||
endpoint_descriptor_index = i;
|
||||
midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc;
|
||||
midi_function[i++] = (struct usb_descriptor_header *) &ms_out_desc;
|
||||
midi_function[i++] = (struct usb_descriptor_header *) &bulk_in_desc;
|
||||
@@ -1009,13 +1028,34 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
goto fail_f_midi;
|
||||
}
|
||||
|
||||
if (gadget_is_superspeed(c->cdev->gadget)) {
|
||||
bulk_in_desc.wMaxPacketSize = cpu_to_le16(1024);
|
||||
bulk_out_desc.wMaxPacketSize = cpu_to_le16(1024);
|
||||
i = endpoint_descriptor_index;
|
||||
midi_function[i++] = (struct usb_descriptor_header *)
|
||||
&bulk_out_desc;
|
||||
midi_function[i++] = (struct usb_descriptor_header *)
|
||||
&bulk_out_ss_comp_desc;
|
||||
midi_function[i++] = (struct usb_descriptor_header *)
|
||||
&ms_out_desc;
|
||||
midi_function[i++] = (struct usb_descriptor_header *)
|
||||
&bulk_in_desc;
|
||||
midi_function[i++] = (struct usb_descriptor_header *)
|
||||
&bulk_in_ss_comp_desc;
|
||||
midi_function[i++] = (struct usb_descriptor_header *)
|
||||
&ms_in_desc;
|
||||
f->ss_descriptors = usb_copy_descriptors(midi_function);
|
||||
if (!f->ss_descriptors)
|
||||
goto fail_f_midi;
|
||||
}
|
||||
|
||||
kfree(midi_function);
|
||||
|
||||
return 0;
|
||||
|
||||
fail_f_midi:
|
||||
kfree(midi_function);
|
||||
usb_free_descriptors(f->hs_descriptors);
|
||||
usb_free_all_descriptors(f);
|
||||
fail:
|
||||
f_midi_unregister_card(midi);
|
||||
fail_register:
|
||||
@@ -1197,14 +1237,21 @@ static void f_midi_free(struct usb_function *f)
|
||||
|
||||
midi = func_to_midi(f);
|
||||
opts = container_of(f->fi, struct f_midi_opts, func_inst);
|
||||
kfree(midi->id);
|
||||
mutex_lock(&opts->lock);
|
||||
kfifo_free(&midi->in_req_fifo);
|
||||
kfree(midi);
|
||||
--opts->refcnt;
|
||||
if (!--midi->free_ref) {
|
||||
kfree(midi->id);
|
||||
kfifo_free(&midi->in_req_fifo);
|
||||
kfree(midi);
|
||||
--opts->refcnt;
|
||||
}
|
||||
mutex_unlock(&opts->lock);
|
||||
}
|
||||
|
||||
static void f_midi_rmidi_free(struct snd_rawmidi *rmidi)
|
||||
{
|
||||
f_midi_free(rmidi->private_data);
|
||||
}
|
||||
|
||||
static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
struct usb_composite_dev *cdev = f->config->cdev;
|
||||
@@ -1219,7 +1266,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
card = midi->card;
|
||||
midi->card = NULL;
|
||||
if (card)
|
||||
snd_card_free(card);
|
||||
snd_card_free_when_closed(card);
|
||||
|
||||
usb_free_all_descriptors(f);
|
||||
}
|
||||
@@ -1263,6 +1310,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
|
||||
midi->buflen = opts->buflen;
|
||||
midi->qlen = opts->qlen;
|
||||
midi->in_last_port = 0;
|
||||
midi->free_ref = 1;
|
||||
|
||||
status = kfifo_alloc(&midi->in_req_fifo, midi->qlen, GFP_KERNEL);
|
||||
if (status)
|
||||
|
||||
@@ -925,8 +925,6 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
||||
*/
|
||||
ncm->port.is_zlp_ok =
|
||||
gadget_is_zlp_supported(cdev->gadget);
|
||||
ncm->port.no_skb_reserve =
|
||||
gadget_avoids_skb_reserve(cdev->gadget);
|
||||
ncm->port.cdc_filter = DEFAULT_FILTER;
|
||||
DBG(cdev, "activate ncm\n");
|
||||
net = gether_connect(&ncm->port);
|
||||
|
||||
@@ -691,6 +691,10 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc;
|
||||
}
|
||||
|
||||
rndis_iad_descriptor.bFunctionClass = rndis_opts->class;
|
||||
rndis_iad_descriptor.bFunctionSubClass = rndis_opts->subclass;
|
||||
rndis_iad_descriptor.bFunctionProtocol = rndis_opts->protocol;
|
||||
|
||||
/*
|
||||
* in drivers/usb/gadget/configfs.c:configfs_composite_bind()
|
||||
* configurations are bound in sequence with list_for_each_entry,
|
||||
@@ -866,11 +870,23 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(rndis);
|
||||
/* f_rndis_opts_ifname */
|
||||
USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis);
|
||||
|
||||
/* f_rndis_opts_class */
|
||||
USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, class);
|
||||
|
||||
/* f_rndis_opts_subclass */
|
||||
USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, subclass);
|
||||
|
||||
/* f_rndis_opts_protocol */
|
||||
USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, protocol);
|
||||
|
||||
static struct configfs_attribute *rndis_attrs[] = {
|
||||
&rndis_opts_attr_dev_addr,
|
||||
&rndis_opts_attr_host_addr,
|
||||
&rndis_opts_attr_qmult,
|
||||
&rndis_opts_attr_ifname,
|
||||
&rndis_opts_attr_class,
|
||||
&rndis_opts_attr_subclass,
|
||||
&rndis_opts_attr_protocol,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -916,6 +932,10 @@ static struct usb_function_instance *rndis_alloc_inst(void)
|
||||
}
|
||||
INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop);
|
||||
|
||||
opts->class = rndis_iad_descriptor.bFunctionClass;
|
||||
opts->subclass = rndis_iad_descriptor.bFunctionSubClass;
|
||||
opts->protocol = rndis_iad_descriptor.bFunctionProtocol;
|
||||
|
||||
descs[0] = &opts->rndis_os_desc;
|
||||
names[0] = "rndis";
|
||||
config_group_init_type_name(&opts->func_inst.group, "",
|
||||
|
||||
@@ -1073,7 +1073,7 @@ struct net_device *gether_connect(struct gether *link)
|
||||
|
||||
if (result == 0) {
|
||||
dev->zlp = link->is_zlp_ok;
|
||||
dev->no_skb_reserve = link->no_skb_reserve;
|
||||
dev->no_skb_reserve = gadget_avoids_skb_reserve(dev->gadget);
|
||||
DBG(dev, "qlen %d\n", qlen(dev->gadget, dev->qmult));
|
||||
|
||||
dev->header_len = link->header_len;
|
||||
|
||||
@@ -64,7 +64,6 @@ struct gether {
|
||||
struct usb_ep *out_ep;
|
||||
|
||||
bool is_zlp_ok;
|
||||
bool no_skb_reserve;
|
||||
|
||||
u16 cdc_filter;
|
||||
|
||||
|
||||
@@ -153,4 +153,39 @@ out: \
|
||||
\
|
||||
CONFIGFS_ATTR_RO(_f_##_opts_, ifname)
|
||||
|
||||
#define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_) \
|
||||
static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\
|
||||
char *page) \
|
||||
{ \
|
||||
struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
|
||||
int ret; \
|
||||
\
|
||||
mutex_lock(&opts->lock); \
|
||||
ret = sprintf(page, "%02x\n", opts->_n_); \
|
||||
mutex_unlock(&opts->lock); \
|
||||
\
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\
|
||||
const char *page, \
|
||||
size_t len) \
|
||||
{ \
|
||||
struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
|
||||
int ret; \
|
||||
u8 val; \
|
||||
\
|
||||
mutex_lock(&opts->lock); \
|
||||
ret = sscanf(page, "%02hhx", &val); \
|
||||
if (ret > 0) { \
|
||||
opts->_n_ = val; \
|
||||
ret = len; \
|
||||
} \
|
||||
mutex_unlock(&opts->lock); \
|
||||
\
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
CONFIGFS_ATTR(_f_##_opts_, _n_)
|
||||
|
||||
#endif /* __U_ETHER_CONFIGFS_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user