Merge branch 'master' of git://git.denx.de/u-boot-usb
* 'master' of git://git.denx.de/u-boot-usb: USB: Use (get|put)_unaligned for accessing wMaxPacketSize usb:gadget:s5p Enable the USB Gadget framework at Exynos4210 (C210 Universal) README: add documentation for CONFIG_USB_ULPI* USB: ULPI: increase error case verbosity USB: ULPI: clean a mixup of return types USB: ULPI: switch argument type from u8 to unsigned
This commit is contained in:
commit
8b0affecb9
8
README
8
README
|
@ -1185,6 +1185,14 @@ The following options need to be configured:
|
|||
for your device
|
||||
- CONFIG_USBD_PRODUCTID 0xFFFF
|
||||
|
||||
- ULPI Layer Support:
|
||||
The ULPI (UTMI Low Pin (count) Interface) PHYs are supported via
|
||||
the generic ULPI layer. The generic layer accesses the ULPI PHY
|
||||
via the platform viewport, so you need both the genric layer and
|
||||
the viewport enabled. Currently only Chipidea/ARC based
|
||||
viewport is supported.
|
||||
To enable the ULPI layer support, define CONFIG_USB_ULPI and
|
||||
CONFIG_USB_ULPI_VIEWPORT in your board configuration file.
|
||||
|
||||
- MMC Support:
|
||||
The MMC controller on the Intel PXA is supported. To
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#define EXYNOS4_ADC_BASE 0x13910000
|
||||
#define EXYNOS4_PWMTIMER_BASE 0x139D0000
|
||||
#define EXYNOS4_MODEM_BASE 0x13A00000
|
||||
#define EXYNOS4_USBPHY_CONTROL 0x10020704
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/io.h>
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mmc.h>
|
||||
#include <pmic.h>
|
||||
#include <usb/s3c_udc.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <max8998_pmic.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -253,3 +256,48 @@ int board_mmc_init(bd_t *bis)
|
|||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_GADGET
|
||||
static int s5pc210_phy_control(int on)
|
||||
{
|
||||
int ret;
|
||||
struct pmic *p = get_pmic();
|
||||
|
||||
if (pmic_probe(p))
|
||||
return -1;
|
||||
|
||||
if (on) {
|
||||
ret |= pmic_set_output(p,
|
||||
MAX8998_REG_BUCK_ACTIVE_DISCHARGE3,
|
||||
MAX8998_SAFEOUT1, LDO_ON);
|
||||
ret |= pmic_set_output(p, MAX8998_REG_ONOFF1,
|
||||
MAX8998_LDO3, LDO_ON);
|
||||
ret |= pmic_set_output(p, MAX8998_REG_ONOFF2,
|
||||
MAX8998_LDO8, LDO_ON);
|
||||
|
||||
} else {
|
||||
ret |= pmic_set_output(p, MAX8998_REG_ONOFF2,
|
||||
MAX8998_LDO8, LDO_OFF);
|
||||
ret |= pmic_set_output(p, MAX8998_REG_ONOFF1,
|
||||
MAX8998_LDO3, LDO_OFF);
|
||||
ret |= pmic_set_output(p,
|
||||
MAX8998_REG_BUCK_ACTIVE_DISCHARGE3,
|
||||
MAX8998_SAFEOUT1, LDO_OFF);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
puts("MAX8998 LDO setting error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct s3c_plat_otg_data s5pc210_otg_data = {
|
||||
.phy_control = s5pc210_phy_control,
|
||||
.regs_phy = EXYNOS4_USBPHY_BASE,
|
||||
.regs_otg = EXYNOS4_USBOTG_BASE,
|
||||
.usb_phy_ctrl = EXYNOS4_USBPHY_CONTROL,
|
||||
.usb_flags = PHY0_SLEEP,
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <part.h>
|
||||
#include <usb.h>
|
||||
|
||||
|
@ -240,7 +241,7 @@ void usb_display_ep_desc(struct usb_endpoint_descriptor *epdesc)
|
|||
printf("Interrupt");
|
||||
break;
|
||||
}
|
||||
printf(" MaxPacket %d", epdesc->wMaxPacketSize);
|
||||
printf(" MaxPacket %d", get_unaligned(&epdesc->wMaxPacketSize));
|
||||
if ((epdesc->bmAttributes & 0x03) == 0x3)
|
||||
printf(" Interval %dms", epdesc->bInterval);
|
||||
printf("\n");
|
||||
|
|
27
common/usb.c
27
common/usb.c
|
@ -49,6 +49,7 @@
|
|||
#include <asm/processor.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <usb.h>
|
||||
#ifdef CONFIG_4xx
|
||||
|
@ -279,30 +280,32 @@ usb_set_maxpacket_ep(struct usb_device *dev, int if_idx, int ep_idx)
|
|||
{
|
||||
int b;
|
||||
struct usb_endpoint_descriptor *ep;
|
||||
u16 ep_wMaxPacketSize;
|
||||
|
||||
ep = &dev->config.if_desc[if_idx].ep_desc[ep_idx];
|
||||
|
||||
b = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
|
||||
ep_wMaxPacketSize = get_unaligned(&ep->wMaxPacketSize);
|
||||
|
||||
if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
|
||||
USB_ENDPOINT_XFER_CONTROL) {
|
||||
/* Control => bidirectional */
|
||||
dev->epmaxpacketout[b] = ep->wMaxPacketSize;
|
||||
dev->epmaxpacketin[b] = ep->wMaxPacketSize;
|
||||
dev->epmaxpacketout[b] = ep_wMaxPacketSize;
|
||||
dev->epmaxpacketin[b] = ep_wMaxPacketSize;
|
||||
USB_PRINTF("##Control EP epmaxpacketout/in[%d] = %d\n",
|
||||
b, dev->epmaxpacketin[b]);
|
||||
} else {
|
||||
if ((ep->bEndpointAddress & 0x80) == 0) {
|
||||
/* OUT Endpoint */
|
||||
if (ep->wMaxPacketSize > dev->epmaxpacketout[b]) {
|
||||
dev->epmaxpacketout[b] = ep->wMaxPacketSize;
|
||||
if (ep_wMaxPacketSize > dev->epmaxpacketout[b]) {
|
||||
dev->epmaxpacketout[b] = ep_wMaxPacketSize;
|
||||
USB_PRINTF("##EP epmaxpacketout[%d] = %d\n",
|
||||
b, dev->epmaxpacketout[b]);
|
||||
}
|
||||
} else {
|
||||
/* IN Endpoint */
|
||||
if (ep->wMaxPacketSize > dev->epmaxpacketin[b]) {
|
||||
dev->epmaxpacketin[b] = ep->wMaxPacketSize;
|
||||
if (ep_wMaxPacketSize > dev->epmaxpacketin[b]) {
|
||||
dev->epmaxpacketin[b] = ep_wMaxPacketSize;
|
||||
USB_PRINTF("##EP epmaxpacketin[%d] = %d\n",
|
||||
b, dev->epmaxpacketin[b]);
|
||||
}
|
||||
|
@ -333,6 +336,7 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
|
|||
struct usb_descriptor_header *head;
|
||||
int index, ifno, epno, curr_if_num;
|
||||
int i;
|
||||
u16 ep_wMaxPacketSize;
|
||||
|
||||
ifno = -1;
|
||||
epno = -1;
|
||||
|
@ -378,8 +382,15 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
|
|||
dev->config.if_desc[ifno].no_of_ep++;
|
||||
memcpy(&dev->config.if_desc[ifno].ep_desc[epno],
|
||||
&buffer[index], buffer[index]);
|
||||
le16_to_cpus(&(dev->config.if_desc[ifno].ep_desc[epno].\
|
||||
wMaxPacketSize));
|
||||
ep_wMaxPacketSize = get_unaligned(&dev->config.\
|
||||
if_desc[ifno].\
|
||||
ep_desc[epno].\
|
||||
wMaxPacketSize);
|
||||
put_unaligned(le16_to_cpu(ep_wMaxPacketSize),
|
||||
&dev->config.\
|
||||
if_desc[ifno].\
|
||||
ep_desc[epno].\
|
||||
wMaxPacketSize);
|
||||
USB_PRINTF("if %d, ep %d\n", ifno, epno);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <config.h>
|
||||
#include <circbuf.h>
|
||||
#include <stdio_dev.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include "usbtty.h"
|
||||
#include "usb_cdc_acm.h"
|
||||
#include "usbdescriptors.h"
|
||||
|
@ -626,6 +627,9 @@ static void usbtty_init_strings (void)
|
|||
usb_strings = usbtty_string_table;
|
||||
}
|
||||
|
||||
#define init_wMaxPacketSize(x) le16_to_cpu(get_unaligned(\
|
||||
&ep_descriptor_ptrs[(x) - 1]->wMaxPacketSize));
|
||||
|
||||
static void usbtty_init_instances (void)
|
||||
{
|
||||
int i;
|
||||
|
@ -688,14 +692,12 @@ static void usbtty_init_instances (void)
|
|||
endpoint_instance[i].rcv_attributes =
|
||||
ep_descriptor_ptrs[i - 1]->bmAttributes;
|
||||
|
||||
endpoint_instance[i].rcv_packetSize =
|
||||
le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
|
||||
endpoint_instance[i].rcv_packetSize = init_wMaxPacketSize(i);
|
||||
|
||||
endpoint_instance[i].tx_attributes =
|
||||
ep_descriptor_ptrs[i - 1]->bmAttributes;
|
||||
|
||||
endpoint_instance[i].tx_packetSize =
|
||||
le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
|
||||
endpoint_instance[i].tx_packetSize = init_wMaxPacketSize(i);
|
||||
|
||||
endpoint_instance[i].tx_attributes =
|
||||
ep_descriptor_ptrs[i - 1]->bmAttributes;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/usb/ch9.h>
|
||||
#include <asm/errno.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include "gadget_chips.h"
|
||||
|
||||
#define isdigit(c) ('0' <= (c) && (c) <= '9')
|
||||
|
@ -127,7 +128,7 @@ static int ep_matches(
|
|||
* where it's an output parameter representing the full speed limit.
|
||||
* the usb spec fixes high speed bulk maxpacket at 512 bytes.
|
||||
*/
|
||||
max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize);
|
||||
max = 0x7ff & le16_to_cpu(get_unaligned(&desc->wMaxPacketSize));
|
||||
switch (type) {
|
||||
case USB_ENDPOINT_XFER_INT:
|
||||
/* INT: limit 64 bytes full speed, 1024 high speed */
|
||||
|
@ -143,7 +144,8 @@ static int ep_matches(
|
|||
return 0;
|
||||
|
||||
/* BOTH: "high bandwidth" works only at high speed */
|
||||
if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) {
|
||||
if ((get_unaligned(&desc->wMaxPacketSize) &
|
||||
__constant_cpu_to_le16(3<<11))) {
|
||||
if (!gadget->is_dualspeed)
|
||||
return 0;
|
||||
/* configure your hardware with enough buffering!! */
|
||||
|
@ -176,7 +178,7 @@ static int ep_matches(
|
|||
/* min() doesn't work on bitfields with gcc-3.5 */
|
||||
if (size > 64)
|
||||
size = 64;
|
||||
desc->wMaxPacketSize = cpu_to_le16(size);
|
||||
put_unaligned(cpu_to_le16(size), &desc->wMaxPacketSize);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <linux/usb/gadget.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
|
@ -586,7 +587,8 @@ static int s3c_ep_enable(struct usb_ep *_ep,
|
|||
if (!_ep || !desc || ep->desc || _ep->name == ep0name
|
||||
|| desc->bDescriptorType != USB_DT_ENDPOINT
|
||||
|| ep->bEndpointAddress != desc->bEndpointAddress
|
||||
|| ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) {
|
||||
|| ep_maxpacket(ep) <
|
||||
le16_to_cpu(get_unaligned(&desc->wMaxPacketSize))) {
|
||||
|
||||
DEBUG("%s: bad ep or descriptor\n", __func__);
|
||||
return -EINVAL;
|
||||
|
@ -603,8 +605,8 @@ static int s3c_ep_enable(struct usb_ep *_ep,
|
|||
|
||||
/* hardware _could_ do smaller, but driver doesn't */
|
||||
if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
|
||||
&& le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(ep))
|
||||
|| !desc->wMaxPacketSize) {
|
||||
&& le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)) !=
|
||||
ep_maxpacket(ep)) || !get_unaligned(&desc->wMaxPacketSize)) {
|
||||
|
||||
DEBUG("%s: bad %s maxpacket\n", __func__, _ep->name);
|
||||
return -ERANGE;
|
||||
|
@ -620,7 +622,7 @@ static int s3c_ep_enable(struct usb_ep *_ep,
|
|||
ep->stopped = 0;
|
||||
ep->desc = desc;
|
||||
ep->pio_irqs = 0;
|
||||
ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
|
||||
ep->ep.maxpacket = le16_to_cpu(get_unaligned(&desc->wMaxPacketSize));
|
||||
|
||||
/* Reset halt state */
|
||||
s3c_udc_set_nak(ep);
|
||||
|
|
|
@ -98,7 +98,7 @@ static int ulpi_request(u32 ulpi_viewport, u32 value)
|
|||
return err;
|
||||
}
|
||||
|
||||
u32 ulpi_write(u32 ulpi_viewport, u8 *reg, u32 value)
|
||||
int ulpi_write(u32 ulpi_viewport, u8 *reg, u32 value)
|
||||
{
|
||||
u32 val = ULPI_RWRUN | ULPI_RWCTRL | ((u32)reg << 16) | (value & 0xff);
|
||||
|
||||
|
@ -107,7 +107,7 @@ u32 ulpi_write(u32 ulpi_viewport, u8 *reg, u32 value)
|
|||
|
||||
u32 ulpi_read(u32 ulpi_viewport, u8 *reg)
|
||||
{
|
||||
u32 err;
|
||||
int err;
|
||||
u32 val = ULPI_RWRUN | ((u32)reg << 16);
|
||||
|
||||
err = ulpi_request(ulpi_viewport, val);
|
||||
|
|
|
@ -39,8 +39,8 @@ static struct ulpi_regs *ulpi = (struct ulpi_regs *)0;
|
|||
|
||||
static int ulpi_integrity_check(u32 ulpi_viewport)
|
||||
{
|
||||
u32 err, val, tval = ULPI_TEST_VALUE;
|
||||
int i;
|
||||
u32 val, tval = ULPI_TEST_VALUE;
|
||||
int err, i;
|
||||
|
||||
/* Use the 'special' test value to check all bits */
|
||||
for (i = 0; i < 2; i++, tval <<= 1) {
|
||||
|
@ -79,9 +79,9 @@ int ulpi_init(u32 ulpi_viewport)
|
|||
return ulpi_integrity_check(ulpi_viewport);
|
||||
}
|
||||
|
||||
int ulpi_select_transceiver(u32 ulpi_viewport, u8 speed)
|
||||
int ulpi_select_transceiver(u32 ulpi_viewport, unsigned speed)
|
||||
{
|
||||
u8 tspeed = ULPI_FC_FULL_SPEED;
|
||||
u32 tspeed = ULPI_FC_FULL_SPEED;
|
||||
u32 val;
|
||||
|
||||
switch (speed) {
|
||||
|
@ -92,8 +92,8 @@ int ulpi_select_transceiver(u32 ulpi_viewport, u8 speed)
|
|||
tspeed = speed;
|
||||
break;
|
||||
default:
|
||||
printf("ULPI: %s: wrong transceiver speed specified, "
|
||||
"falling back to full speed\n", __func__);
|
||||
printf("ULPI: %s: wrong transceiver speed specified: %u, "
|
||||
"falling back to full speed\n", __func__, speed);
|
||||
}
|
||||
|
||||
val = ulpi_read(ulpi_viewport, &ulpi->function_ctrl);
|
||||
|
@ -127,9 +127,9 @@ int ulpi_set_pd(u32 ulpi_viewport, int enable)
|
|||
return ulpi_write(ulpi_viewport, reg, val);
|
||||
}
|
||||
|
||||
int ulpi_opmode_sel(u32 ulpi_viewport, u8 opmode)
|
||||
int ulpi_opmode_sel(u32 ulpi_viewport, unsigned opmode)
|
||||
{
|
||||
u8 topmode = ULPI_FC_OPMODE_NORMAL;
|
||||
u32 topmode = ULPI_FC_OPMODE_NORMAL;
|
||||
u32 val;
|
||||
|
||||
switch (opmode) {
|
||||
|
@ -140,8 +140,8 @@ int ulpi_opmode_sel(u32 ulpi_viewport, u8 opmode)
|
|||
topmode = opmode;
|
||||
break;
|
||||
default:
|
||||
printf("ULPI: %s: wrong OpMode specified, "
|
||||
"falling back to OpMode Normal\n", __func__);
|
||||
printf("ULPI: %s: wrong OpMode specified: %u, "
|
||||
"falling back to OpMode Normal\n", __func__, opmode);
|
||||
}
|
||||
|
||||
val = ulpi_read(ulpi_viewport, &ulpi->function_ctrl);
|
||||
|
@ -154,15 +154,15 @@ int ulpi_opmode_sel(u32 ulpi_viewport, u8 opmode)
|
|||
return ulpi_write(ulpi_viewport, &ulpi->function_ctrl, val);
|
||||
}
|
||||
|
||||
int ulpi_serial_mode_enable(u32 ulpi_viewport, u8 smode)
|
||||
int ulpi_serial_mode_enable(u32 ulpi_viewport, unsigned smode)
|
||||
{
|
||||
switch (smode) {
|
||||
case ULPI_IFACE_6_PIN_SERIAL_MODE:
|
||||
case ULPI_IFACE_3_PIN_SERIAL_MODE:
|
||||
break;
|
||||
default:
|
||||
printf("ULPI: %s: unrecognized Serial Mode specified\n",
|
||||
__func__);
|
||||
printf("ULPI: %s: unrecognized Serial Mode specified: %u\n",
|
||||
__func__, smode);
|
||||
return ULPI_ERROR;
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ int ulpi_serial_mode_enable(u32 ulpi_viewport, u8 smode)
|
|||
|
||||
int ulpi_suspend(u32 ulpi_viewport)
|
||||
{
|
||||
u32 err;
|
||||
int err;
|
||||
|
||||
err = ulpi_write(ulpi_viewport, &ulpi->function_ctrl_clear,
|
||||
ULPI_FC_SUSPENDM);
|
||||
|
@ -214,7 +214,7 @@ int ulpi_reset_wait(u32) __attribute__((weak, alias("__ulpi_reset_wait")));
|
|||
|
||||
int ulpi_reset(u32 ulpi_viewport)
|
||||
{
|
||||
u32 err;
|
||||
int err;
|
||||
|
||||
err = ulpi_write(ulpi_viewport,
|
||||
&ulpi->function_ctrl_set, ULPI_FC_RESET);
|
||||
|
|
|
@ -262,4 +262,8 @@
|
|||
#define CONFIG_PMIC_I2C
|
||||
#define CONFIG_PMIC_MAX8998
|
||||
|
||||
#define CONFIG_USB_GADGET
|
||||
#define CONFIG_USB_GADGET_S3C_UDC_OTG
|
||||
#define CONFIG_USB_GADGET_DUALSPEED
|
||||
|
||||
#endif /* __CONFIG_H */
|
||||
|
|
|
@ -76,6 +76,7 @@ enum {
|
|||
|
||||
#define MAX8998_LDO3 (1 << 2)
|
||||
#define MAX8998_LDO8 (1 << 5)
|
||||
#define MAX8998_SAFEOUT1 (1 << 4)
|
||||
|
||||
#define MAX8998_I2C_ADDR (0xCC >> 1)
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ int ulpi_init(u32 ulpi_viewport);
|
|||
* ULPI_FC_LOW_SPEED, ULPI_FC_FS4LS
|
||||
* returns 0 on success, ULPI_ERROR on failure.
|
||||
*/
|
||||
int ulpi_select_transceiver(u32 ulpi_viewport, u8 speed);
|
||||
int ulpi_select_transceiver(u32 ulpi_viewport, unsigned speed);
|
||||
|
||||
/*
|
||||
* Enable/disable VBUS.
|
||||
|
@ -66,7 +66,7 @@ int ulpi_set_pd(u32 ulpi_viewport, int enable);
|
|||
*
|
||||
* returns 0 on success, ULPI_ERROR on failure.
|
||||
*/
|
||||
int ulpi_opmode_sel(u32 ulpi_viewport, u8 opmode);
|
||||
int ulpi_opmode_sel(u32 ulpi_viewport, unsigned opmode);
|
||||
|
||||
/*
|
||||
* Switch to Serial Mode.
|
||||
|
@ -78,7 +78,7 @@ int ulpi_opmode_sel(u32 ulpi_viewport, u8 opmode);
|
|||
* Switches immediately to Serial Mode.
|
||||
* To return from Serial Mode, STP line needs to be asserted.
|
||||
*/
|
||||
int ulpi_serial_mode_enable(u32 ulpi_viewport, u8 smode);
|
||||
int ulpi_serial_mode_enable(u32 ulpi_viewport, unsigned smode);
|
||||
|
||||
/*
|
||||
* Put PHY into low power mode.
|
||||
|
@ -108,7 +108,7 @@ int ulpi_reset(u32 ulpi_viewport);
|
|||
*
|
||||
* returns 0 on success, ULPI_ERROR on failure.
|
||||
*/
|
||||
u32 ulpi_write(u32 ulpi_viewport, u8 *reg, u32 value);
|
||||
int ulpi_write(u32 ulpi_viewport, u8 *reg, u32 value);
|
||||
|
||||
/*
|
||||
* Read the ULPI PHY register content via the viewport.
|
||||
|
|
|
@ -199,7 +199,7 @@ struct usb_endpoint_descriptor {
|
|||
u8 bmAttributes;
|
||||
u16 wMaxPacketSize;
|
||||
u8 bInterval;
|
||||
} __attribute__ ((packed)) __attribute__ ((aligned(2)));
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct usb_interface_descriptor {
|
||||
u8 bLength;
|
||||
|
|
Loading…
Reference in New Issue